	OUTPUT "arcomage.rom"

	;defpage 0, $0000, $4000 
    ;defpage 1, $4000 , $8000 
    ;defpage 2, $8000, $4000 
    ;defpage 3, $C000, $4000 


DEBUG_MODE	equ	0							;0 = false, 1 = debug mode
DEMO_MODE	equ	0							
;-----------------------------------------------
;- vram address labels
CHRTBL equ 0x0000
NAMTBL equ 0x1800
CLRTBL equ 0x2000
SPRTBL equ 0x3800
SPRATR equ 0x1B00

FORCLR equ 0xF3E9  ; Foreground color (+1 = background color , +1 border)

JIFFY  equ 0xFC9E

SNSMAT equ 0x0141  ; keyb bios call	

CLIKSW equ 0xF3DB  ; bios click switch

VDP_ADDR equ 0x99
VDP_DATA equ 0x98


DISSCR equ 0x41
ENASCR equ 0x44

;-----------------------------------------------

NUMBER_OF_CARDS	equ	102
PLAYER_MIN_CARDS equ 30

;screen locations for counters and widgets
PLAYER_TOWER   equ NAMTBL + 384;12-0 	
PLAYER_WALL    equ NAMTBL + 387;12-3	
CPU_TOWER 	   equ NAMTBL + 414;12-30	
CPU_WALL  	   equ NAMTBL + 411;12-27	

PLAYER_FOES    equ NAMTBL + 482;15-2		
PLAYER_DUNGEON equ NAMTBL + 515;16-3		
CPU_FOES       equ NAMTBL + 508;15-28		
CPU_DUNGEON    equ NAMTBL + 539;16-27	

PLAYER_GEMS    equ NAMTBL + 642;20-2		
PLAYER_MAGIC   equ NAMTBL + 675;21-3		
CPU_GEMS       equ NAMTBL + 668;20-28	
CPU_MAGIC      equ NAMTBL + 699;21-27	

PLAYER_BRICKS  equ NAMTBL + 678;21-6		
PLAYER_QUARRY  equ NAMTBL + 682;21-10		
CPU_BRICKS     equ NAMTBL + 696;21-24		
CPU_QUARRY     equ NAMTBL + 692;21-20		

PLAYER_MINICARDS   equ NAMTBL + 647;20-7 
PLAYER_CARD_DETAIL equ NAMTBL + 6;0-6	 
CPU_CARD_DETAIL    equ NAMTBL + 16;0-16 

DROP_TEXT_LOC	equ	NAMTBL + 593 ; 18-17


LCARDART_F_TILE		equ 187
RCARDART_F_TILE		equ 211

LCARDART_VRAM_FONT_B1_COLOR	equ	CLRTBL + (91*8)
RCARDART_VRAM_FONT_B1_COLOR	equ	CLRTBL + (139*8)
LCARDART_VRAM_FONT_B2_COLOR	equ	CLRTBL + (91*8) + (256*8)
RCARDART_VRAM_FONT_B2_COLOR	equ	CLRTBL + (139*8) + (256*8)


LCARDART_VRAM_EDGE_B1_COLOR	equ	CLRTBL + (1*8)		
RCARDART_VRAM_EDGE_B1_COLOR	equ	CLRTBL + (11*8)		
LCARDART_VRAM_EDGE_B2_COLOR	equ	CLRTBL + (1*8) + (256*8)	
RCARDART_VRAM_EDGE_B2_COLOR	equ	CLRTBL + (11*8) + (256*8)


LCARDART_FONT_CHAR_SPACE	equ	112
RCARDART_FONT_CHAR_SPACE	equ	160

FONT_OFFSET_LEFT_CARD		equ 48
FONT_OFFSET_RIGHT_CARD		equ	96
SHOP_RED_FONT_OFFSET		equ FONT_OFFSET_LEFT_CARD
SHOP_GREEN_FONT_OFFSET		equ FONT_OFFSET_RIGHT_CARD
SHOP_BLUE_FONT_OFFSET		equ 144


PLAYER_CARD_DETAIL_CH_BLK1 	equ CHRTBL + (LCARDART_F_TILE * 8)
CPU_CARD_DETAIL_CH_BLK1    	equ CHRTBL + (RCARDART_F_TILE * 8)
PLAYER_CARD_DETAIL_CH_BLK2 	equ CHRTBL + (LCARDART_F_TILE * 8) + (256*8)
CPU_CARD_DETAIL_CH_BLK2    	equ CHRTBL + (RCARDART_F_TILE * 8) + (256*8)
PLAYER_CARD_DETAIL_CH_BLK3 	equ CHRTBL + (LCARDART_F_TILE * 8) + (256*8)*2
CPU_CARD_DETAIL_CH_BLK3    	equ CHRTBL + (RCARDART_F_TILE * 8) + (256*8)*2

PLAYER_CARD_DETAIL_COL_BLK1 	equ CLRTBL + (LCARDART_F_TILE * 8)
CPU_CARD_DETAIL_COL_BLK1    	equ CLRTBL + (RCARDART_F_TILE * 8)
;PLAYER_CARD_DETAIL_COL_BLK2 	equ CLRTBL + (LCARDART_F_TILE * 8) + (256*8)
;CPU_CARD_DETAIL_COL_BLK2    	equ CLRTBL + (RCARDART_F_TILE * 8) + (256*8)
;PLAYER_CARD_DETAIL_COL_BLK3 	equ CLRTBL + (LCARDART_F_TILE * 8) + (256*8)*2
;CPU_CARD_DETAIL_COL_BLK3    	equ CLRTBL + (RCARDART_F_TILE * 8) + (256*8)*2

MINICARD_VRAM_0		equ	NAMTBL + (16*32) + 7
MINICARD_VRAM_1		equ	MINICARD_VRAM_0 + 3
MINICARD_VRAM_2		equ	MINICARD_VRAM_1 + 3
MINICARD_VRAM_3		equ	MINICARD_VRAM_2 + 3
MINICARD_VRAM_4		equ	MINICARD_VRAM_3 + 3
MINICARD_VRAM_5		equ	MINICARD_VRAM_4 + 3

MINICARD_GRAYOUT_OFFSET	equ	30;153

QUIT_DIALOG_LOCATION	equ	(8*32)+12


CURSOR_Y	equ 130		;131	
CURSOR_X_F	equ 60		;First

PLAYER_ABOUT_TO_DIE_THRESHOLD	equ	11
PLAYER_ABOUT_TO_DIE_NEARLY_THRESHOLD	equ	20
AI_ABOUT_TO_DIE_THRESHOLD	equ	5
AI_ABOUT_TO_DIE_WEIGHT_UPDATE	equ	15
AI_CARD45_MIN_CPU_TOWER	equ	15

TOWER_HEIGHT_OFFSET		equ	0
WALL_HEIGHT_OFFSET		equ	1
FOES_VALUE_OFFSET		equ	2
DUNGEON_VALUE_OFFSET	equ	3
GEMS_VALUE_OFFSET		equ	4
MAGIC_VALUE_OFFSET		equ	5
BRICKS_VALUE_OFFSET		equ	6
QUARRY_VALUE_OFFSET		equ	7


;-----------------------------------------------
TEXT_SPACE		equ	32
ASC_0			equ	48
ASC_A			equ	65
BIG_NUMBER_0	equ 91

TOWER_FRONT_TILE	equ	21
TOWER_BACK_TILE		equ	22
TOWER_FRONT_TOP_TILE	equ	23
TOWER_BACK_TOP_TILE		equ	24
;player
P_WALL_FRONT_TILE	equ	25
P_WALL_BACK_TILE	equ	26
P_WALL_FRONT_TOP_TILE	equ	27
P_WALL_BACK_TOP_TILE	equ	28

;cpu	
C_WALL_FRONT_TILE	equ	25
C_WALL_BACK_TILE	equ	26

CARD_TEXT_WIDTH		equ	8

BLUE_TILE			equ	7
BROWN_TILE			equ	16
GREEN_TILE			equ	25



BLUE_SQUARE_CORNER_NW	equ	96
BROWN_SQUARE_CORNER_NW	equ	91
GREEN_SQUARE_CORNER_NW	equ	101

SQUARE_OFFSET_CORNER_NE	equ	2
SQUARE_OFFSET_CORNER_SW	equ	0
SQUARE_OFFSET_CORNER_SE	equ	2
SQUARE_OFFSET_LEFT		equ 3
SQUARE_OFFSET_RIGHT		equ 4
SQUARE_OFFSET_UP		equ 1
SQUARE_OFFSET_DOWN		equ 1


CARD_REG_SIZE		equ	26 ;every single card reg size 

MAX_CARDS_GAME		equ 101 ;(0-MAX_CARDS_GAME)
MASK_MAX_CARDS_GAME equ 01111111b


;----------------------------------------------
;battle
BATTLE_PLAYER_LOSES	equ	NAMTBL + (32*13)+10
BATTLE_PLAYER_GAMEOVER_TXT_LOCATION	equ NAMTBL + (32*10)+11

;----------------------------------------------
;shop
SHOP_TITLE					equ	15
SHOP_CARDSINDECK			equ	90
SHOP_CARDSINDECK_COUNTER	equ	(4*32)+27
SHOP_CARDSOWNER				equ	314
SHOP_CARDSOWNER_COUNTER		equ	(9*32)+27
SHOP_COINS					equ	506
SHOP_COINS_COUNTER			equ	(14*32)+27
SHOP_CARD_DETAIL			equ	111
SHOP_FILTER_CARDS			equ	652
SHOP_FILTER					equ	625
SHOP_ACTION					equ	(10*32) + 11

SHOP_TOKEN_BLUE_OFFSET		equ	0
SHOP_TOKEN_BROWN_OFFSET		equ	9
SHOP_TOKEN_GREEN_OFFSET		equ	18

SHOP_TOKEN_BLUE				equ	1
SHOP_TOKEN_BLUE_GREYOUT		equ	154

SHOP_TILE_ARROW_IN			equ	251
SHOP_TILE_ARROW_OUT			equ 63
SHOP_TILE_CARDS_INOUT		equ	60

SHOP_ARROW_TOP				equ 58
SHOP_ARROW_BOTTOM			equ 59

SHOP_WORD_BUY				equ 64


;----------------------------------------------
;main menu
MMENU_TITLE					equ	172-64
;MMENU_SUBTITLE				equ	172+32-64
MMENU_CURSOR_START			equ	172-3+(32*4)+2
MMENU_FIRST_OPTION_START	equ 172+(32*4)+2
;----------------------------------------------
;story mode
STORY_TITLE					equ	NAMTBL+32+12
;STORY_ENEMY_LIST_FIRST		equ	NAMTBL+(32*4)+12

;----------------------------------------------
CARD_NW_TILE				equ	94
CARD_NE_TILE				equ	95
CARD_SW_TILE				equ	96
CARD_SE_TILE				equ	97
CARD_TOP_TILE				equ	99
CARD_BOTTOM_TILE			equ	98
CARD_LEFT_TILE				equ	93
CARD_RIGHT_TILE				equ	91



;background fx
BFX0			equ		2
BFX1			equ		1


TINY_MAGE_EYES_PERIOD		equ	20

;----------------------------------------------
;keys
KEY_ESC			equ 0x0407
KEY_RIGHT		equ 0x8008
KEY_DOWN		equ 0x4008
KEY_UP			equ 0x2008
KEY_LEFT		equ 0x1008
KEY_SPACE		equ 0x0108
KEY_1			equ 0x0200
KEY_2			equ 0x0400
KEY_3			equ 0x0800
KEY_4			equ 0x1000
KEY_M           equ 0x0404
KEY_P           equ 0x2004
KEY_C           equ 0x0103

;------------------------
;original from Ramones (http://karoshi.auic.es/index.php?topic=628.0)
ENASLT:   		equ  024h
RSLREG: 		equ 0138h
EXPTBL: 		equ 0FCC1h ; Bios Slot / Expansion Slot
SLTTBL:			equ 0FCC5h
;original from Ramones END
;-----------------------







	;page	0
	org		0
	include "cardsart.asm"
	ds      04000h-$,0FFh       ; Filled up 16KB


	;page	1
	org		0x4000
romheader:
	byte "AB"
	word BEGIN
	word 0,0,0,0,0,0

	include	"cardsart2.asm"


BEGIN:

	di
	im 		1
	ld 		sp,0xF380
	
	;call	clean_wyz_ram							;I got some issues with wyz player if I don't clean its working area on some msx models (HB-F9S)
	
	call 	search_slotset

	call	sram_detection

	call	setup_page3_activation

	;call	set_new_palette_if_P_pressed
	call	check_cheat_mode

	call 	screen2x16
	
	call	load_sprites
	call	set_spr_attrb_4_title_scr
	call	display_title_screen
	
	call 	screen2x16
	
	call	scroll_text
	
	call	cls_screen
	
	call	load_cards_regs
	
	;call	load_battle_patterns	
	;call	shop_load_patterns
	;call	show_all_patterns
	;jr		$-4
	
	;call	clean_vram
	
	call	cls_sprites

	;call	show_all_sprites
	;jr		$
	
	call	init_vars

	call	init_player_deck_status
	call	shop_init_counters
	
	call	init_music
	
main_menu_entry_point:	
	
	call	init_main_menu
	
	jr.		mmenu_main_loop
	
	ret



/*
clean_wyz_ram:
	ld		hl,buffer_player
	ld		a,0
	ld		d,h
	ld		e,l
	inc		de
	ld		bc,(text_buffer) - (buffer_player)
	ldir
	

	ret
	*/

/*	
set_new_palette_if_P_pressed:

	ld		hl,KEY_P
	call	get_keyboard
	and		a
	ret		z				;not pressed
	
	ld	a,[0x002d]			; read MSX version
	or	a					; is it MSX1?
	ret	z					; then there's no need to use it anyway
	ld	a,[0x0007]			; get first VDP write port
	ld	c,a
	inc	c					; prepare to write register data
	di						; interrupts could screw things up
	xor	a					; from color 0
	out	(c),a
	ld	a,128+16			; write R#16
	out	(c),a
	ei
	inc	c					; prepare to write palette data
	ld	b,32				; 16 color * 2 bytes for palette data
	ld	hl,paletteMSX1
	otir
	ret

paletteMSX1:
		dw	$000,$000,$612,$724,$226,$336,$262,$727
		dw	$272,$373,$562,$674,$512,$266,$666,$777	

*/

check_cheat_mode:
	xor		a
	ld		[cheat],a
	
	ld		hl,KEY_C 
	call	get_keyboard 
	and		a
	ret		z		

	ld		a,1
	ld		[cheat],a

	ret


;hl	dest
;a		lines
;b		bytes to skip when line ends
;c		font offset
;ix	src
;returns a=0 if zero was found, a=1 if zero wasn't found
;all basic registers are modified
;if [ix] contains spaces, they won't be written ,just skipped
;if 0 is found doesn't write anything else
;else writes until reaches 'a' lines
print_string0_mem_with_skip:
	push	bc
print_string0_mem_with_skip_line_loop:	
	ld		b,CARD_TEXT_WIDTH
	push	af					;save number of lines to go

print_string0_mem_with_skip_char_loop:
	xor		a
	cp		[ix]
	jr		z,print_string0_mem_with_skip_fill_0
	
	ld		a,[ix]
	cp		TEXT_SPACE			;if space, skip, don't write
	jr		z,print_string0_mem_with_skip_char_loop_skip_space
	;ok, we are going to write but must have into account font offset
	add		c					;c holds font offset
	ld		[hl],a

print_string0_mem_with_skip_char_loop_skip_space:	
	inc		ix
	inc		hl
	djnz	print_string0_mem_with_skip_char_loop

	pop		af					;remaining line on a
	dec		a					;one line less to go
	pop		bc					;b bytes to skip
	push	bc					;save byte to skip for next loop
	push	af					;save flags & number of lines to go
print_string0_mem_with_skip_bytes1_loop:	
	inc		hl					
	djnz	print_string0_mem_with_skip_bytes1_loop	;skipping b bytes
	
	pop		af					;get flags back
	jr		nz,print_string0_mem_with_skip_line_loop		;do we finish with all lines?
	jr		print_string0_mem_with_skip_end_zero_not_found

print_string0_mem_with_skip_fill_0:	
	;we can return, buffer was already cleaned
	
	pop		af
	pop		bc		;leaving stack ok
	xor		a		;returns a=0 if 0 was found
	ret
	
print_string0_mem_with_skip_end_zero_not_found:	
	pop		bc		;leaving stack ok
	ld		a,1		;returns a=1 if 0 wasn't found
	ret







;Deadlock number 1 - any player holds in his hand cards with forced_to_play cards and doesn't have resources to do it
;					 end of the game for such player
;return		a=0 if not deadlock was found
;			a=3 if there is cpu deadlock , player wins
;			a=4 if there is player deadlock, cpu wins
;TODO: lot of duplicated code ... REFACTOR!!!!!! (checking on player & cpu are similar routines )
look_for_deadlocks:
	;deadlock 1
	;player
	ld		hl,player_hand
	ld		b,6
look_for_deadlocks_cannot_be_dropped_keep_searching_loop:
	push	bc
	ld		a,[hl]
	push	hl
	push	af

	call	get_card_address
	inc		hl
	ld		a,[hl]
	bit		4,a								;cannot be discarded flag?
	jr		nz,look_for_deadlocks_cannot_be_dropped_keep_searching
	pop		af
	jr		look_for_deadlocks_cannot_be_dropped_check_cpu_hand						;warning 2 extra words in the stack
look_for_deadlocks_cannot_be_dropped_keep_searching:
	;second check... is playable ?
	ld		hl,player_tower_height			;checking player
	pop		af								;card number is here
	call	is_card_playable	
	and		a								;if playable , no more validations on player
	jr		nz,look_for_deadlocks_cannot_be_dropped_check_cpu_hand					;warning 2 extra words in the stack
	pop		hl
	inc		hl
	pop		bc
	djnz	look_for_deadlocks_cannot_be_dropped_keep_searching_loop
	;if we are here , bad thing ... player
	;we've checked whole player hand and all of them are forced to play but doesn't have resources to play any of those ... deadlock!
	;TODO: what happens when we've got deadlock
	ld		a,4
	ret
	
	;enemy
look_for_deadlocks_cannot_be_dropped_check_cpu_hand:
	pop		hl
	pop		hl																		;set stack right height

	

	ld		hl,cpu_hand
	ld		b,6
look_for_deadlocks_cannot_be_dropped_keep_searching_loop_2:
	push	bc
	ld		a,[hl]
	push	hl
	push	af

	call	get_card_address
	inc		hl
	ld		a,[hl]
	bit		4,a								;cannot be discarded flag?
	jr		nz,look_for_deadlocks_cannot_be_dropped_keep_searching_2
	pop		af
	jr		look_for_deadlocks_cannot_be_dropped_no_more_checks						;warning 2 extra words in the stack
look_for_deadlocks_cannot_be_dropped_keep_searching_2:
	;second check... is playable ?
	ld		hl,cpu_tower_height				;checking cpu
	pop		af								;card number is here
	call	is_card_playable	
	and		a								;if playable , no more validations on player
	jr		nz,look_for_deadlocks_cannot_be_dropped_no_more_checks					;warning 2 extra words in the stack
	pop		hl
	inc		hl
	pop		bc
	djnz	look_for_deadlocks_cannot_be_dropped_keep_searching_loop_2
	;if we are here , bad thing ... cpu
	;we've checked whole cpu hand and all of them are forced to play but doesn't have resources to play any of those ... deadlock!
	;TODO: what happens when we've got deadlock
	ld		a,3
	ret

look_for_deadlocks_cannot_be_dropped_no_more_checks:
	pop		hl
	pop		hl

	xor		a								;return 0 => no deadlocks at all
	ret






;updates battle background music tempo depending on player wall+tower
if_about_to_die:
	
	;is music on?
	ld		a,[music_onoff]
	and		a
	ret		z
	
	;if (ptower+pwall =< 5 and about_to_die!=2) {about_to_die==2, set tempo 4) 
	;if (ptower+pwall =< 10 and about_to_die!=1) {about_to_die==1, set tempo 5)
	;if (ptower+pwall > 10 and about_to_die!=0) {about_to_die==0, set tempo 6)
	ld		a,[player_wall_height]
	ld		b,a
	ld		a,[player_tower_height]
	add		b
	ld		b,a			;save a for later (if we need to restore volume)
	
	cp		PLAYER_ABOUT_TO_DIE_THRESHOLD
	jr		c,if_about_to_die_set_status_abouttodie
	;cp		PLAYER_ABOUT_TO_DIE_NEARLY_THRESHOLD
	;jr		c,if_about_to_die_set_status_nearlyabouttodie
	
	ld		a,[about_to_die]
	and		a
	jr		nz,if_about_to_die_set_status_notabouttodie
	ret
	
if_about_to_die_set_status_abouttodie:
	ld		a,[about_to_die]
	cp		2
	ret		z
	ld		a,2
	ld		[about_to_die],a
	
	call	PLAYER_OFF
	ld		a,TUNE_BATTLE
	call	start_music
	ld		a,[SONG_0]
	dec		a
	dec		a
	ld		[TEMPO],a
	
	ret

/*
if_about_to_die_set_status_nearlyabouttodie:
	ld		a,[about_to_die]
	cp		1
	ret		z
	ld		a,1
	ld		[about_to_die],a

	call	PLAYER_OFF
	ld		a,TUNE_BATTLE
	call	start_music

	ld		a,[SONG_0]
	dec		a
	ld		[TEMPO],a
	ret
*/
	
if_about_to_die_set_status_notabouttodie:
	ld		a,b
	cp		PLAYER_ABOUT_TO_DIE_NEARLY_THRESHOLD
	ret		c
	;will restore music speed if is over PLAYER_ABOUT_TO_DIE_NEARLY_THRESHOLD
	
	xor		a
	ld		[about_to_die],a
	ld		a,[SONG_0]						;first byte is default tempo
	ld		[TEMPO],a
	ret






check_if_battle_ends:

	call	battle_check_victory_conditions
	;			a=1 if there is victory condition, player wins
	;			a=2 if there is victory condition, cpu wins
	cp		0
	jr		z,check_if_battle_ends_look_for_deadlocks					;if a==0 no victory conditions, let's look for deadlocks
	
	;a must be 1 or 2
	call	battle_ends_resolution	
	;rewards punishments etc
	cp		2
	jr		z,check_if_battle_ends_gameoverman
	jr		check_if_battle_ends_finish
	
	
check_if_battle_ends_look_for_deadlocks:	
	call	look_for_deadlocks
	or		a															;0?
	ret		z

	;a must be 3 or 4
	call	battle_ends_resolution
	;rewards punishments etc

check_if_battle_ends_finish:

	pop		af 										;mmloop ret address is in the stack
	pop		af										;TODO:do that updating the stack pointer
	pop		af
	pop		af
	
	jr.		main_menu_entry_point


check_if_battle_ends_gameoverman:
	call	PLAYER_OFF
	jr.		BEGIN


	ret






;a = amount to increase
;modifies [shop_coins]
;bc,hl,af
add_and_check_coins:
	ld		b,0
	ld		c,a
	ld		hl,[shop_coins]	
	add		hl,bc
	ld		a,h
	cp		0x03
	jr		c,add_and_check_coins_add				;c-> h byte less than 0x3  , nc->h 0x3 or greater
	jr		nz,add_and_check_coins_check_top_coins	;nz-> not 3, so is greater ... top!!
	;h is 3, check lower byte (l)
	ld		a,l
	cp		0xE7
	jr		nc,add_and_check_coins_check_top_coins
add_and_check_coins_add:
	ld		[shop_coins],hl
	ret
	
add_and_check_coins_check_top_coins
	ld		hl,999
	ld		[shop_coins],hl
	ret




;ret
;a = color number
;updates tinymage_eyes_spr_attr
;modifies a, bc,hl
next_tinymage_eyes_color:

	ld		a,[tinymage_eyes_struct]
	ld		b,0
	ld		c,a
	
	cp		TINIMAGE_EYES_COLOR_LIST_SIZE 
	jr		z,next_tinymage_eyes_color_set0
	inc		a
	jr		next_tinymage_eyes_color_after_setting_index
next_tinymage_eyes_color_set0:
	xor		a
next_tinymage_eyes_color_after_setting_index:	
	ld		[tinymage_eyes_struct],a
	
	ld		hl,tinymage_eyes_colors
	add		hl,bc
	ld		a,[hl]

	ret



;show message (TODO: & art/sfx/etc) & waits keystroke
;TODO: something different for deadlocks????
;a=1 player wins
;a=2 cpu wins
;a=3 player wins cos cpu deadlock
;a=4 cpu wins cos player deadlock
;return
; a=0 game not finished yet
; a=1 game over player wins!
; a=2 game over player defeated!
battle_ends_resolution:	
	;/////////////////
	;TODO: it must show very clear why game is finished. So far just a delay. Sound + message + press key/space/whatever?

	push	af
	
	cp		3
	jr		z,.set_enemy_deadlock_message
	cp		4
	jr		z,.set_player_deadlock_message
	jr		.show_must_go_on
.set_enemy_deadlock_message:	
	ld		hl,deadlock_enemy
	jr		.carryon
.set_player_deadlock_message:	
	ld		hl,deadlock_player	
	
.carryon:	
	ld		de,NAMTBL+(32*12)+9
	call	display_enemyname
	
.show_must_go_on:	
	
	
	
	ld		a,0
	call	print_battle_background
	ld		a,1
	call	print_battle_background

	call	print_towers_walls_on_background
	
	ld		a,0
	call	display_battle_background_tower_and_wall
	ld		a,1
	call	display_battle_background_tower_and_wall
	
	halt								
	
	
	;ld		b,SFX_SHOPACTION
	;call	INICIA_EFECTO
	;ld		a,10
	;call	INICIA_SONIDO
	ld		b,10
	call	INICIA_EFECTO
	
	ld		a,[player_tower_height]
	and		a
	jr		nz,battle_ends_resolution_beforedelay
	call	hide_player_flag	
	
battle_ends_resolution_beforedelay:	
	ld		b,10
battle_ends_resolution_delay:
	push	bc
	
	ld		hl,NAMTBL+(32*10)+9
	ld		b,0
	ld		a,[combat_finished_txt]
	ld		c,a
	xor		a
	call	0x056

	halt
	halt
	halt
	halt

	call	update_debris_status_and_scenes
	call	display_debris_fx	

	halt
	halt

		
	ld		hl,combat_finished_txt
	ld		de,NAMTBL+(32*10)+9
	call	display_enemyname
	
	halt
	halt
	halt
	
	call	update_debris_status_and_scenes
	call	display_debris_fx	

	halt
	halt
	halt

	
	pop		bc
	djnz	battle_ends_resolution_delay
	
	
	call	wait_press_space
	;/////////////////

	call	hide_cursor_sprites
	;hide enemy tower flag
	ld		a,193
	ld		[flags_fx_struct+5+8],a
	ld		[flags_fx_struct+5+8+4],a
	
	ld		hl,flags_fx_struct+5+8
	ld		bc,4*2
	ld		de,SPRATR + (15*4)
	call	0x05c
	

	;tinymage eyes init
	xor		a
	ld		[tinymage_eyes_struct],a
	ld		a,TINY_MAGE_EYES_PERIOD
	ld		[tinymage_eyes_struct+1],a
	
	ld		ix,tmp_buffer
	ld		[ix],111				;Y
	ld		[ix+1],192				;X
	ld		[ix+2],24				;pattern number
	ld		[ix+3],0				;first color		
	ld		hl,tmp_buffer
	ld		de,SPRATR + (6*4)
	ld		bc,4
	call	0x05c
	;end tinymage eyes init
	
	pop		af

	cp		1
	jr		z,battle_ends_resolution_player_wins
	cp		3									
	jr		z,battle_ends_resolution_player_wins

	;battle lost
	ld		a,[quest_battle]
	and		a
	jr		z,battle_ends_resolution_training_lost
	;quest battle lost!
	call	remove_heaviest_player_card
	cp		255												;if a=255 game over! it will be 0! so game over!
	jr		z,battle_ends_resolution_game_over
	
	call	display_player_battle_quest_lost
	;call	wait_press_space
	call	wait_press_space_flashing_eyes
	xor		a												;it's not game over yet
	ret
	
	
battle_ends_resolution_game_over:	
	call	display_player_battle_quest_gameover	
	call	wait_press_space
	ld		a,2												;it's game over
	ret
	
	
battle_ends_resolution_training_lost:	
	call	display_player_battle_lost
	;call	wait_press_space
	call	wait_press_space_flashing_eyes
	xor		a												;it's not game over yet
	ret


battle_ends_resolution_player_wins:
	ld		a,[quest_battle]
	and		a
	jr		z,battle_ends_resolution_player_wins_no_quest
	ld		a,[quest_current_enemy]
	inc		a
	
	cp		10												;last enemy defeated?
	jr		z,battle_ends_resolution_gameover_finalboss_defeated
	
	ld		[quest_current_enemy],a
		
	ld		b,a	
	ld		a,15	
	ld		c,a
battle_ends_resolution_player_wins_loop:
	add		c
	djnz	battle_ends_resolution_player_wins_loop
	
	;50+(current_enemy(0-10)*25)

	push	af												;save amount to display
	call	add_and_check_coins
	pop		af
	jr		battle_quest_ends_resolution_display
battle_ends_resolution_player_wins_no_quest:
	call	calc_coins_earned_training						;a return number of coins
	push	af
	call	add_and_check_coins
	pop		af
battle_ends_resolution_display:
	call	display_player_battle_wins	
	;call	wait_press_space
	call	wait_press_space_flashing_eyes
	xor		a												;it's not game over yet
	ret
	
	
battle_ends_resolution_gameover_finalboss_defeated:	
	call	display_player_gameover_finalboss_defeated
	call	wait_press_space
	ld		a,2				;1
	
	ret

battle_quest_ends_resolution_display
	call   display_player_battle_quest_wins	
	;call	wait_press_space
	call	wait_press_space_flashing_eyes
	xor		a
	
	ret







;shop_cards_owned must be updated
;return
;a with the valued
calc_coins_earned_training:
	ld		a,[shop_cards_owned]			;a=x
	srl		a								;a=int(a/2)
	ret
	
	


;This is the punishment for the player losing a game
; and updates player_deck_status
;returns a=removed card number
;		 a=255 not removed, game over man!
remove_heaviest_player_card:
	;first check if he has at least 30 cards, if he has 30 (or less), game over! 
	ld		a,[shop_cards_owned]
	cp		31
	jr		c,remove_card_from_player_deck_gameover					;Cannot remove more cards ... game over straight away!
	;look for card to remove
	xor		a
	ld		[tmp_buffer3],a							;card number init
	ld		[tmp_buffer3+1],a						;weight init
	ld		b,MAX_CARDS_GAME+1
	ld		hl,player_deck_status+MAX_CARDS_GAME
remove_card_from_player_deck_loop:	
	ld		a,[hl]	
	bit		6,a										;it's owned bit set?
	jr		z,remove_card_from_player_deck_loop_nextcard

	ld		a,b										;card number is one less
	dec		a
	push	hl
	push	bc
	call	get_card_address						
	pop		bc
	inc		hl
	inc		hl
	ld		c,[hl]									;saving hl pointing at card weight	
	pop		hl										;restore hl
	ld		a,[tmp_buffer3+1]
	cp		c										;a-c, old-new , old>=new ->ncarry, old<new ->carry
	jr		nc,remove_card_from_player_deck_loop_nextcard
	;update
	ld		a,c
	ld		[tmp_buffer3+1],a						;writing down new card candidate weight
	ld		a,b
	dec		a										;card number is one less
	ld		[tmp_buffer3],a							;writing down new card candidate number
remove_card_from_player_deck_loop_nextcard:	
	;continue
	dec		hl										;next playerdeckstatus
	djnz	remove_card_from_player_deck_loop		;counter loop

	;ok. here tmp_buffer3 has the card candidate to be removed
	ld		hl,player_deck_status
	ld		d,0
	ld		a,[tmp_buffer3]
	ld		e,a
	add		hl,de									;hl points at player_deck_status to be modified
	ld		a,[hl]
	cpl												
	set		6,a										;not owned
	set		7,a										;not into battle deck
	cpl												;a 6th and 7th bit is 0 for sure
	ld		[hl],a									;set new value
													;removed!
	;update number of cards counters ; TODO:check if it's needed
	call	shop_init_counters
	ld		a,[shop_cards_in_deck]					;we must have 30 cards in deck at least
	cp		30
	jr		nc,remove_card_from_player_deck_at_least_30
	;we have less than 30 cards in deck	(must be 29! maybe less in debug mode ;-) )
	call	assign_indeck_one_owned_card
	call	shop_init_counters						;refresh counters again
	;carry on ...
remove_card_from_player_deck_at_least_30:	
	ld		a,[tmp_buffer3]							;just removed card number 
	ret

remove_card_from_player_deck_gameover:
	ld		a,255									;255 means no removed (game over man!!!)
	ret








;looks for the first owned card not in deck making that in deck 
assign_indeck_one_owned_card:
	ld		b,MAX_CARDS_GAME+1
	ld		hl,player_deck_status+MAX_CARDS_GAME
assign_indeck_one_owned_card_loop:	
	ld		a,[hl]
	bit		6,a										;is it owned?
	jr		z,assign_indeck_one_owned_card_next_card
	;it's owned
	bit		7,a										;is it indeck?
	jr		nz,assign_indeck_one_owned_card_next_card	;if already indeck , next card
	;not indeck , let's set that indeck
	or		11000000b								
	ld		[hl],a									;save
	ret												;work done!

assign_indeck_one_owned_card_next_card:
	dec		hl
	djnz	assign_indeck_one_owned_card_loop
	ret








;battle_check_victory_conditions
;return		a=0 if not victory condition
;			a=1 if there is victory condition, player wins
;			a=2 if there is victory condition, cpu wins
;modifies just af
battle_check_victory_conditions:
	;two conditions
	;any of the towers is cero
	;OR
	;any of both players has 99 for wall and tower
	
	;1)
	ld		a,[player_tower_height]
	and		a
	jr		z,battle_check_victory_conditions_player_loses
	
	ld		a,[cpu_tower_height]
	and		a
	jr		z,battle_check_victory_conditions_cpu_loses
	
	
	;2)
	ld		a,[player_tower_height]
	cp		99
	jr		nz,battle_check_victory_conditions_check_cpu
	ld		a,[player_wall_height]
	cp		99
/*	jr		nz,battle_check_victory_conditions_check_cpu
	ld		a,[player_foes_value]
	cp		99
	jr		nz,battle_check_victory_conditions_check_cpu
	ld		a,[player_gems_value]
	cp		99
	jr		nz,battle_check_victory_conditions_check_cpu
	ld		a,[player_bricks_value]
	cp		99
*/
	jr		z,battle_check_victory_conditions_cpu_loses				;player wins, cpu loses


battle_check_victory_conditions_check_cpu:

	ld		a,[cpu_tower_height]
	cp		99
	jr		nz,battle_check_victory_conditions_not_victory
	ld		a,[cpu_wall_height]
	cp		99
/*	
	jr		nz,battle_check_victory_conditions_not_victory
	ld		a,[cpu_foes_value]
	cp		99
	jr		nz,battle_check_victory_conditions_not_victory
	ld		a,[cpu_gems_value]
	cp		99
	jr		nz,battle_check_victory_conditions_not_victory
	ld		a,[cpu_bricks_value]
	cp		99
*/
	jr		z,battle_check_victory_conditions_player_loses			;player loses, cpu wins
	
		
battle_check_victory_conditions_not_victory:
	xor		a
	ret

battle_check_victory_conditions_player_loses:
	ld		a,2
	ret

battle_check_victory_conditions_cpu_loses:
	ld		a,1
	ret






;Story mode routines

;simple quick routine to display quest status... TODO: let's do it with great graphics/music/sfx
display_story_mode:
	call	cls_screen	
	
	ld		hl,story_mode_title_txt				;title
	ld		de,STORY_TITLE+1 + (32*8)
	ld		bc,5
	call	0x005c

	ld		hl,story_mode_stage_txt				
	ld		de,STORY_TITLE + (32*11)
	ld		bc,5
	call	0x005c
	
	ld		a,[quest_current_enemy]
	inc		a
	ld		hl,shop_action
	call	calc_two_digits_counter_dest_hl

	ld		hl,shop_action			
	ld		de,STORY_TITLE + (32*11) + 6
	ld		bc,2
	call	0x005c
	

	call	set_enemy_name_for_later_flashing_use
	;shop_action holds enemy name
	ld		hl,shop_action			
	ld		de,STORY_TITLE + (32*13) + 1
	ld		bc,6
	call	0x005c

	ret


	
	IF DEMO_MODE==0
story_mode_setup:

	ld		a,1
	ld		[quest_battle],a

	call	display_story_mode
	call	wait_press_space

	ld		a,[quest_current_enemy]
	ld		hl,quest_enemy_list_ptr
	
	add		a,a
	add		a,a								;a=a*4=quest_current_enemy*4
	
	ld		b,0
	ld		c,a
	add		hl,bc	
	;hl(enemyX_deck address) = (quest_current_enemy*4)+quest_enemy_list_ptr
	inc		hl
	inc		hl								;first two bytes are ptr at enemy's name
	
	ex		de,hl
	
	ld		a,[de]
	ld		l,a
	inc		de
	ld		a,[de]
	ld		h,a								;hl=ptr
	
	ld		a,[hl]							;background number
	inc		hl
	ld		[enemy_current_deck_pointer],hl

	call	battle_common_setup
	call	battle_main_loop

	ret		;TODO: not needed

	ENDIF
;Story mode routines END




battle_training_setup:
	xor		a
	ld		[quest_battle],a
	
	ld		hl,0x0303								;between 0 to 2
	call	rand_max
	;a=a*2											;ptr are 2 bytes long
	add		a	
	ld		c,a
	ld		b,0
	
	ld		a,[shop_cards_owned]
	cp		41										;a-40 , a>41 -> nc
	jr		nc,battle_training_setup_check_l2
	;l1
	ld		hl,training_enemy_l1_list_ptr
	jr		battle_training_setup_set_enemy_deck

battle_training_setup_check_l2:
	cp		61
	jr		nc,battle_training_setup_check_l3
	;l2
	ld		hl,training_enemy_l2_list_ptr
	jr		battle_training_setup_set_enemy_deck

battle_training_setup_check_l3:
	cp		81
	jr		nc,battle_training_setup_check_l4
	;l3
	ld		hl,training_enemy_l3_list_ptr
	jr		battle_training_setup_set_enemy_deck
	
battle_training_setup_check_l4:
	;l4
	ld		hl,training_enemy_l4_list_ptr
battle_training_setup_set_enemy_deck:
	add		hl,bc									;hl ptr to deck address
	ld		e,[hl]
	inc		hl
	ld		d,[hl]
	ex		de,hl									;hl address to deck

	ld		a,[hl]									;background number
	inc		hl
	ld		[enemy_current_deck_pointer],hl
	
	;set about_to_die
	push	af
	xor		a
	ld		[about_to_die],a
	pop		af
	
	call	battle_common_setup	

	call	battle_main_loop
	
	ret		;TODO: not needed
	
	
	
;a background number	
battle_common_setup:
	push	af
	call	DISSCR
	
	call	PLAYER_OFF
	
	;call	refresh_good_rand						;init random numbers list
	
	
	call	load_battle_patterns
	call	init_vars_for_battle
	
;	call	display_player_hand						;already displayed

	call	build_player_deck_for_battle
	
	IF	DEMO_MODE==1
	ld		hl,player_cards_deck
	ld		a,94					;vampire
	ld		[hl],a
	ENDIF
	
	ld		hl,[enemy_current_deck_pointer]
	call	setup_player_cpu_max_cards_masks

	call	clear_shop_card_deck_buffer	
	
	ld		a,TUNE_BATTLE
	call	start_music	

		
	call	display_two_digits_counters
	call	display_one_digits_counters
	;call	display_towers_walls	
	call	init_player_and_cpu_hand
	
	call	load_battle_screen
	
	pop		af										;a background number
	push	af
	call	init_background_for_new_game
	
	pop		af										;a background number
	call	background_fx_init
	
	
	;first time it's displayed
	;update player card call
	ld		hl,cursor_data+1			;draw card TODO: make sub
	ld		a,[hl]
	ld		b,0
	ld		c,a
	ld		hl,player_hand
	add		hl,bc
	ld		a,[hl]
	ld		l,LCARDART_F_TILE
	call	print_card	
	
	call	setup_cursor_sprites
	xor		a
	ld		[cursor_flash_struct],a	
	inc		a
	ld		[cursor_flash_struct+1],a


	call	set_enemy_name_for_later_flashing_use
	ld		a,25
	ld		[shop_flashing_flags_counter],a					;init wizard names counter

	
	ld		a,[dump_flags]
	and		00000111b					;remove old flags from shop
	or		00000101b					;set new flags
	ld		[dump_flags],a
	
	call	init_debris_structs
	
	call	flags_fx_init				;will set the update flag too
	
	call	set_enemy_name_for_later_flashing_use	
	
	ld		a,209
	ld		bc,64*4
	ld		hl,SPRATR
	call	0x0056						;disables all sprites
	
	
	call	ENASCR
	
	ret
	
	
	

;battle main loop
battle_main_loop:
	xor		a
	ld		[prev_turn],a				;previous turn player , initially 0

battle_main_loop_loop:					;TODO:tidy up this labels, initalization , etc

	call	keyboard_polling

	ld		a,[prev_turn]							
	and		a							;how was the previous player/cpu?
	jr		z,battle_main_loop_previous_player
	ld		a,[turn]					;previous was cpu
	dec		a							;if non zero flag => a was 0 => current player is the player
	call	nz,update_player_turn_resources

	jr		battle_main_loop_previous_check_end
	
battle_main_loop_previous_player:		
	ld		a,[turn]
	dec		a									;if zero flag => a was 1 => current player is cpu
	call	z,update_cpu_turn_resources
	


battle_main_loop_previous_check_end:
	ld		a,[turn]
	;save previous player
	ld		[prev_turn],a
	
	and		a									;who's next?
	jr		nz,battle_main_loop_cpu_turn		

	jr		battle_main_loop_turn_check_end

battle_main_loop_cpu_turn:						;cpu turn
	ld		a,[cpu_delay]
	dec		a
	ld		[cpu_delay],a
	jr		nz,battle_main_loop_turn_check_end	;delay (cpu logic will be apply later) (delay)
	call	cpu_turn
	ld		a,60;120								;reset delay
	ld		[cpu_delay],a
battle_main_loop_turn_check_end:

	call	if_about_to_die						;music stress

;TODO: tower/wall/background must be changed ... just calculated when it's needed, rewriten all the time
	;ld		hl,battle_background1
	;ld		[pointer_battle_backgrnd],hl
	ld		a,0
	call	print_battle_background
	ld		a,1
	call	print_battle_background

	call	print_towers_walls_on_background
	
	call	update_background_fx
	
	call	update_towerflags_fx
	
	call	update_debris_status_and_scenes
	
	call	update_cursor_if_forced_to_drop

	
	halt								;vdp int after painting screen (dump)

	call	display_background_fx

;always
	;render battle background + towers + walls								;*************************************************************************************************************************************
	;ld		a,[dump_flags]
	;cp		0x04
	;jr		nz,battle_main_after_render_battle_background	;don't render battle background

	ld		a,0
	call	display_battle_background_tower_and_wall
	ld		a,1
	call	display_battle_background_tower_and_wall
	
battle_main_after_render_battle_background:


	;render left card
	ld		a,[dump_flags]
	bit		0,a
	jr		z,battle_main_after_render_left_card	;don't render left card


	;ld		hl,tmp_buffer
	;ld		[pointer_to_buffer],hl
	;ld		a,LCARDART_F_TILE
	call	display_card

battle_main_after_render_left_card:



	;render right card
	ld		a,[dump_flags]
	bit		1,a
	jr		z,battle_main_after_render_right_card	;don't render right card
		
	;ld		hl,shop_card_deck_buffer
	;ld		[pointer_to_buffer],hl
	;ld		a,RCARDART_F_TILE
	call	display_card
	ld		a,[dump_flags]
	bit		3,a										;do we have to render dropped text/fx/whatever?
	jr		z,battle_main_after_render_right_card
	ld		hl,drop_text
	ld		bc,5
	ld		de,NAMTBL+(32*14)+17
	call	0x05c
	
	ld		b,8
	call	INICIA_EFECTO
	
	
battle_main_after_render_right_card:	
	
	call	display_two_digits_counters
	call	display_one_digits_counters
	


	call	display_cursor
	call	display_player_hand						;TODO: without this sometimes is now properly rendered
													;I definitely need to refactor the battle main loop
													;following Jon Cortazar advice 
	call	display_towerflags_fx					;*************************************************************************************************************************************

	call	check_if_battle_ends

	

	IF DEBUG_MODE==1
	ld		a,[show_debug_vars]
	and		a
	jr		z,battle_main_afterdisplayingdebugvalues
	call	debug_display_counters
battle_main_afterdisplayingdebugvalues:	
	call	check_if_cheat_key_pressed
	ENDIF	

/*
	;delay

	ld		hl,0
battle_main_loop_delay:		
	ld		b,0
battle_main_loop_delay_2:
	
	djnz	battle_main_loop_delay_2
	dec		hl
	jr		nz,battle_main_loop_delay
	;;;;;;;;;;;;;;;
*/	
	
	
	call	update_cursor_flashing
	
	call	update_and_display_wizards_names
	
	call	display_debris_fx
	
	;call	REPRODUCE_EFECTO
	
	jr.		battle_main_loop_loop	
	
	ret

	
	
;takes into account player_max_cards_mask
;returns a = card number
;Modifies all basic registers (af,bc,de)
select_random_card_for_player:
	push	hl
	ld		a,[shop_cards_in_deck]
	ld		h,a
	
	ld		de,player_max_cards_mask
	ld		a,[de]
	ld		l,a
	call	rand_max
	
	ld		hl,player_cards_deck
	ld		d,0
	ld		e,a
	add		hl,de
	ld		a,[hl]
	pop		hl
	ret
	
	


;takes into account cpu_max_cards_mask
;hl = enemy deck
;returns a=card number
select_random_card_for_ai:
	push	hl
	ld		a,[hl]
	push	hl
	ld		h,a						;h number of cards in deck
	
	ld		de,cpu_max_cards_mask
	ld		a,[de]
	ld		l,a
	call	rand_max
	
	pop		hl
	inc		hl						;pointing at first enemy's card
	ld		d,0
	ld		e,a
	add		hl,de
	ld		a,[hl]
	pop		hl
	
	ret

;hl= enemy card deck
setup_player_cpu_max_cards_masks:

	;for cpu_max_cards_mask
	ld		a,[hl]						;hl is pointing at enemydeck. First byte is the deck length
	call	calc_mask
	ld		[cpu_max_cards_mask],a

	;for player_max_cards_mask
	ld		a,[shop_cards_in_deck]
	call	calc_mask
	ld		[player_max_cards_mask],a
	
	ret






update_cursor_if_forced_to_drop:
	;if force to drop flag
	ld		a,[forced_to_drop]
	and		a
	ret		z
	;and it's player turn
	ld		a,[turn]
	and		a
	ret		nz
	
	ld		a,1			;drop always!
	ld		[cursor_data],a

	ret








;a=number
;ret a=mask
;TODO: need to code that by shifting bits
calc_mask:
	bit		7,a
	jr		nz,calc_mask_7
	bit		6,a
	jr		nz,calc_mask_6
	bit		5,a
	jr		nz,calc_mask_5
	bit		4,a
	jr		nz,calc_mask_4
	bit		3,a
	jr		nz,calc_mask_3
	bit		2,a
	jr		nz,calc_mask_3

		
calc_mask_7:
	ld		a,11111111b
	ret

calc_mask_6:
	ld		a,01111111b
	ret

calc_mask_5:
	ld		a,00111111b
	ret

calc_mask_4:
	ld		a,00011111b
	ret

calc_mask_3:
	ld		a,00001111b
	ret

calc_mask_2:
	ld		a,00000111b
	ret
	
;I don't need to implement all






;player_foes_value = player_foes_value + player_dungeon_value
;player_gems_value = player_gems_value + player_magic_value
;player_bricks_value = player_bricks_value + player_quarry_value
; same for the cpu

update_player_turn_resources:
	ld		hl,player_foes_value
	ld		a,[player_dungeon_value]
	ld		bc,0x6300
	call	add_integer_value
	
	ld		hl,player_gems_value
	ld		a,[player_magic_value]
	ld		bc,0x6300
	call	add_integer_value

	ld		hl,player_bricks_value
	ld		a,[player_quarry_value]
	ld		bc,0x6300
	call	add_integer_value

	ret


;[hl] = [hl] + a 
;a value to add (or substract)
;bc b max value , c lower value
;hl	 mem address
;checks overflows
;doesn't modify hl.de



update_cpu_turn_resources:

	ld		hl,cpu_foes_value
	ld		a,[cpu_dungeon_value]
	ld		bc,0x6300
	call	add_integer_value

	ld		hl,cpu_gems_value
	ld		a,[cpu_magic_value]
	ld		bc,0x6300
	call	add_integer_value

	ld		hl,cpu_bricks_value
	ld		a,[cpu_quarry_value]
	ld		bc,0x6300
	call	add_integer_value

	ret









cpu_turn:

	call	ai_medium_play_card

	;clean discard visual flag for cpu (right card)
	ld		a,[dump_flags]
	and		11110111b								
	ld		[dump_flags],a


    ld		a,[tmp_buffer3]
    ld		b,0
    ld		c,a
    ld		hl,cpu_hand
    add		hl,bc					;hl pointing at cpu hand position
    ld		a,[hl]					;a holds card number
    
    
    
    push	af						;
									
	ld		a,[tmp_buffer3+1]		;let's check if drop or play
	and		a
	ld		[tmp_buffer3+10],a			;save whether discard or not //113 (f14*c8) card size on screen + 1
	jr		z,cpu_turn_discard		;z= discard
									;!z play card
	
	pop		af							
    push	af						;a = card number and saved
    ;turn must be 1!!!
    call	apply_card_effects
    ;a must be 0 if not ... error!!!
    
									;discard played card (without checks)	
	
	
cpu_turn_discard:	
	pop		af						;restore card number
	
	ld		b,a
	ld		a,[tmp_buffer3]
	push	af						;save card position in hand
	
	push	af
    ld		a,[dump_flags]
	and		11111110b
	or		0x02
	ld		[dump_flags],a
    pop		af
	
	ld		a,b
	ld		l,RCARDART_F_TILE
	call	print_card	


	ld		a,[tmp_buffer3+10]
	and		a						;discard?
	jr		nz,cpu_turn_discard_not_FX
	;discard FX
	;;;shop_card_deck_buffer
	
	;hl	dest
;a		lines
;ix	src
;returns a=0 if zero was found, a=1 if zero wasn't found
;all basic registers are modified

	ld		a,[dump_flags]
	or		00001000b								;set render dropped text/fx/whatever on right card 
	ld		[dump_flags],a
	
	;just in case ... remove play again flag. (if we are in play again status, dropping card must clear such status)
	xor		a
	ld		[play_again],a
	;
	jr		cpu_turn_discard_end


cpu_turn_discard_not_FX:
	;clean SFX
	
	ld		hl,shop_card_deck_buffer				;right card (cpu card) buffer dest	
	ld		bc,(14*10)+1+1
	add		hl,bc
	xor		a
	ld		[hl],a
	push	hl
	pop		de
	inc		de
	ld		bc,4
	ldir	
	
	;
cpu_turn_discard_end:
	pop		af						;a = card position in hand
	call	discard_cpu_card


	ld		a,[forced_to_drop]							;it could be 0,1 or 2
	cp		0
														;if a > 0 forced_to_drop flag
	jr		z,cpu_turn_discard_drop_end					;if forced_to_drop == 0 ==> exit
	dec		a											;now forced_to_drop is 1 or 0 after dec
	ld		[forced_to_drop],a							;save forced_to_drop flag
	;and		a											;if forced_to_drop==0, it means used to be 1 few steps ago
	;jr		nz,discard_player_selected_card_drop_end		;so, preserve forced_to_drop flag to 1
	ld		a,1											;if forced_to_drop==1 it means used to be 2	
	ld		[play_again],a								;and set play again for next turn
	;xor		a
	;ret	a==0 to check play again condition
	
cpu_turn_discard_drop_end:	
	

	ld		a,[play_again]
	and		a						;play again?;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	jr		nz,cpu_turn_end			;true => don't update turn (still same player (cpu)
	xor		a
	ld		[turn],a				;player turn

cpu_turn_end:
	ret






;a = card number
;returns hl, card mem address
;it modifies hl,bc,a,de
get_card_address:
	ld		d,a
	ld		e,CARD_REG_SIZE
	call	multiply		;hl=despl=(card number * card reg size)

	ld		bc,cards_regs
	
	add		hl,bc			;hl pointing at the right card mem address
	
	ret



;a - card number
;hl - base var address (player_tower_height or cpu_tower_height)
;return a=0 false, a=1 true and [tmp_buffer3+2]=weight
is_card_playable:
	push	hl
	pop		ix				;ix base vars address

	ld		hl,tmp_buffer3+2
	push	hl
	pop		iy				;iy address to save ai_weight
	
	call	get_card_address
	
	inc		hl				;flags
	ld		a,[hl]
	bit		0,a							;brown?
	jr		nz,is_card_playable_brown
	bit		1,a							;blue?
	jr		nz,is_card_playable_blue	
										;green
	ld		a,[ix+FOES_VALUE_OFFSET]	;a=var green value
	jr		is_card_playable_color_done
is_card_playable_brown:	
	ld		a,[ix+BRICKS_VALUE_OFFSET]	;a=var brown value
	jr		is_card_playable_color_done	
is_card_playable_blue:	
	ld		a,[ix+GEMS_VALUE_OFFSET]	;a=var blue value


is_card_playable_color_done:
	push	af							
	inc		hl
	ld		a,[hl]						;a=weight
	ld		[iy],a						;[tmp_buffer+1]=weight
	inc		hl							;hl points at card cost
	
	pop		af
	cp		[hl]						;a<[hl] =>  mem var < card cost?
	jr		c,is_card_playable_false
	
	ld		a,1							;ret true
	ret

is_card_playable_false:
	xor		a							;ret false
	ret




;updates [tmp_buffer3] and [tmp_buffer3+1] for ai_medium_play_card
look_for_first_not_forced_to_play_card:
	ld		hl,cpu_hand
	ld		b,0
look_for_first_not_forced_to_play_card_loop	
	push	hl
	push	bc
	
	ld		a,[hl]
	call	get_card_address
	inc		hl
	ld		a,[hl]
	bit		4,a
	jr		z,look_for_first_not_forced_to_play_card_found
	
	pop		bc
	pop		hl
	inc		hl
	inc		b
	ld		a,b
	cp		5
	jr		z,look_for_first_not_forced_to_play_card_not_found
	jr		look_for_first_not_forced_to_play_card_loop
	
look_for_first_not_forced_to_play_card_not_found:
	;we should never be reaching here cos there is a deadlock validator
	;TODO:eventually remove this code
	ld		a,5
	ld		[tmp_buffer3],a
	ld		a,[cpu_hand+5]
	call	get_card_address
	inc		hl
	inc		hl
	inc		hl					;pointing at cost
	ld		a,[hl]
	ld		[tmp_buffer3+1],a
	ret
	
look_for_first_not_forced_to_play_card_found:
	pop		af						;a=b hand position
	pop		hl						;hl hand address position
		
	ld		[tmp_buffer3],a
	ld		a,[hl]					;a
	call	get_card_address
	inc		hl
	inc		hl
	inc		hl					;pointing at cost
	ld		a,[hl]
	ld		[tmp_buffer3+1],a
	ret
	
	
	
;This is ment just for updating [tmp_buffer3+1]
;input
;a card number
;[tmp_buffer3+1] current weight
;ret
;[tmp_buffer3+1] updated if it's needed
update_weight_if_builds_wallortower:
	;checking if card a is increasing wall and/or tower
	push	bc
	push	de
	push	hl
	push	ix
	
	call	get_card_address
	push	hl
	pop		ix

	;check tower
	ld		a,[ix+4]
	bit		7,a
	jr		nz,update_weight_if_builds_wallortower_wall
	;positive
	and		a
	jr		nz,update_weight_if_builds_wallortower_update
	;tower negative or 0

update_weight_if_builds_wallortower_wall:
	ld		a,[ix+5]
	bit		7,a
	jr		nz,update_weight_if_builds_wallortower_end		;negative , no more checks
	and		a
	jr		z,update_weight_if_builds_wallortower_end		;cero , no more checks
	;so , it's positive
update_weight_if_builds_wallortower_update:

	ld		a,AI_ABOUT_TO_DIE_WEIGHT_UPDATE
	ld		hl,tmp_buffer3+2
	ld		b,255
	ld		c,0
	call	add_integer_value
	;done
update_weight_if_builds_wallortower_end:	
	pop		ix
	pop		hl
	pop		de
	pop		bc
	

	ret
	
	

;look for heaviest playable card (have enough resources to play that) from cpu hand
;using tmp_buffer (card pos) and tmp_buffer+1 (weight) (initially 0,0 ) chosen card to play 
;return tmp_buffer+1 !=0 => tmp_buffer=card position in hand to play (tmp_buffer+1 holds weight(useless?))
;		tmp_buffer+1 ==0 => tmp_buffer=card position in hand to discard
;
;Special conditions:
; 1 - Those cards which are increasing magic/quarry/dungeon must be discarded with highest priority if magic/quarry/dungeon are 9 
; 2 - 'Shift' card if selected but card player wall is lower than enemy wall must be discarded and not played  
; 3 - If wizard wall+tower <=5 (or any other threshold) (=> about to die) when analizing weights (for those cards which are playable), building cards (increase wall/tower) will add a weight bonus just for that ai call,
; so they will be more likely to be played. Flag calculated and stored at [tmp_buffer3+5]
; 4 - Card powerburn 45, must be discarded if selected and cpu tower<15
; 5 - Card parity 47, should be used just when cpu has lower magic than player
; 6 - Card flood water 30, if lowest wall is playerwall will be applied else discarded
; 7 - Card copping tech 7, check quarries, dicard if it's not convenient
; 8 - Cards 14,16 earth quake and collapse must be discarded if player quarry is just 1
; 9 - Card gobbling mob(74) cannot be used if cpu wall+tower =<3
;10 - Card Berserker (99) cannot be used if tower =<3
;11 - Card Tremors (12) must not be used when player has wall 0
ai_medium_play_card:


	ld		a,[forced_to_drop]									;if this flag is set (cos a draw one , drop one card), we will use same
																;algorithm as if the ai doesn't find any card to be played
																;we shouldn't find deadlocks cos there is a deadlock validater in the battle main 
																;loop
	and		a
	jr		z,ai_medium_play_card_not_forced_to_discard
	;forced to discard
	;basically it's going to use same algorith to discard when there are not enough resources to play any card in hand
	;but we need to initialise tmp_buffer and tmp_buffer with one of the cards costs and its position in hand
	;init
	
	call	look_for_first_not_forced_to_play_card
	
	jr.		ai_medium_play_card_discard


ai_medium_play_card_not_forced_to_discard:
	ld		hl,tmp_buffer3
	push	hl
	pop		ix
	ld		[ix],0	
	ld		[ix+1],0				;tmp_buffer, tmp_buffer+1
	ld		[ix+2],0
	
	;get ready for special condition 3. Let's recon if enemywall+enemytower <= AI_ABOUT_TO_DIE_THRESHOLD (about to die)
	ld		a,[cpu_tower_height]
	ld		b,a
	ld		a,[cpu_wall_height]
	add		b	
	cp		AI_ABOUT_TO_DIE_THRESHOLD		;current summatory - AI_ABOUT_TO_DIE_THRESHOLD 
	jr		c,ai_medium_play_card_cond3_set
	xor		a								;unset
	jr		ai_medium_play_card_cond3_write_flag
ai_medium_play_card_cond3_set:
	ld		a,1								;set
ai_medium_play_card_cond3_write_flag:
	ld		[tmp_buffer3+5],a				;special condition 3 flag set
	
		
	ld		hl,cpu_hand+5	
	ld		b,6						;loop 6 times				
	
ai_medium_play_card_loop:	
	ld		a,[hl]					;card number
	ld		[tmp_buffer3+4],a		;saving card number for later use

	push	bc
	push	hl						;saving hand current address in hand	
	ld		hl,cpu_tower_height	
	push	ix
	call	is_card_playable		;a set, hl set , return a=0/1 [tmp_buffer+2]=weight	
	pop		ix
	pop		hl
	pop		bc

	and		a						;playable?
	jr		z,ai_medium_play_card_next	;not playable ... check next card	



	;if playable and special condition3
	ld		a,[tmp_buffer3+5]
	and		a						;a==0 => enemy is not about to die
	jr		nz,ai_medium_play_update_weight_if_builds_wallortower
	jr		ai_medium_play_DONT_update_weight
ai_medium_play_update_weight_if_builds_wallortower:
	ld		a,[tmp_buffer3+4]		;a holds cardnumber
	call	update_weight_if_builds_wallortower					;perform the weight update if needed
ai_medium_play_DONT_update_weight:
	
	
									;playable ... let's check it's weight vs maximum weight so far [tmp_buffer+1]<[tmp_buffer+2]?	
	ld		a,[tmp_buffer3+2]		;tmp_buffer3+2 address holds playable card weight (because of the is_card_playable call)
	ld		c,a
	ld		a,[tmp_buffer3+1]		
	cp		c						;a<c ? [tmp_buffer+1] < [tmp_buffer+2] ? max weight < current_card_weight
	jr		c,ai_medium_play_card_newmax
	jr		ai_medium_play_card_next ;max weight is still max weight
	
ai_medium_play_card_newmax:
	push	bc						;save b counter
	ld		a,b
	dec		a
	ld		[ix],a					;save hand position (0-5)
	pop		bc						;restore b counter
	ld		[ix+1],c				;save weight on mem
	;jr		ai_medium_play_card_next

ai_medium_play_card_next:					
	dec		hl						;next card in hand (counting down)
	djnz	ai_medium_play_card_loop
	
	;tmp_buffer3 (card pos) and tmp_buffer3+1 (weight) at this point , (0,0) means ... no playable card (so , ia must select a card to be discarded (logic below))
	; actually it will be (X,0) ... if tmp_buffer3+1 == 0 {discard tmp_buffer3 will contain discard card position in hand} . (X,0) is how I am going to leave tmp_buffer3
	; when returning from this routine
	
	ld		a,[tmp_buffer3+1]
	and		a						
	jr		z,ai_medium_play_card_discard					;discard?
	jr		ai_medium_play_card_end							;not discard , goto end

ai_medium_play_card_discard:
	;I presume all cards are suitable to be dropped 
	;Not all cards are suitable to be dropped ... I must take into account  cannot be discarded flag
	;just looking for higher cost tmp_buffer,tmp_buffer+1 must be 0,0
	ld		hl,cpu_hand+5	
	ld		b,6						;loop 6 times
	
ai_medium_play_card_discard_loop:	
	push	hl
	
	ld		a,[hl]
	push	bc
	call	get_card_address
	pop		bc

	push	hl
	pop		ix
	
	ld		a,[ix+1]
	bit		4,a
	jr		z,ai_medium_play_card_discard_loop_not_forced_to_play
	;this carded has forced to play cannot be discarded flag, let's skip it
	jr		ai_medium_play_card_discard_next
	
ai_medium_play_card_discard_loop_not_forced_to_play:	
	ld		a,[ix+3]				;cost
	ld		c,a						;c = card cost
	ld		a,[tmp_buffer3+1]		;a = max cost
	cp		c						;a<c ?
;	pop		hl						;restore  hand pointer
	jr		c,ai_medium_play_card_new_drop_candidate	
	jr		ai_medium_play_card_discard_next

ai_medium_play_card_new_drop_candidate:
	ld		a,b
	dec		a
	ld		[tmp_buffer3],a			;position in hand updated
	ld		a,c
	ld		[tmp_buffer3+1],a		;update new cost

ai_medium_play_card_discard_next:
	pop		hl
	dec		hl						;new hand pointer
	djnz	ai_medium_play_card_discard_loop
	xor		a
	ld		[tmp_buffer3+1],a		;set as discard (0 for tmp_buffer+1) ,[tmp_buffer] has the position to discard
	
	ret

ai_medium_play_card_end:	

	ld		a,[tmp_buffer3]
	ld		hl,cpu_hand
	ld		b,0
	ld		c,a
	add		hl,bc
	ld		a,[hl]						;a card number

	ld		[tmp_buffer3+4],a			;saving card number for later use

	;extra validations!
	;Special conditions 1) (please see routine header comments)
	; checking magic/quarry/dungeon ,  cpu_dungeon_value/cpu_magic_value/cpu_quarry_value
	; 
	ld		a,[cpu_quarry_value]
	cp		9							;a-9, if a>=9 nc, else (a<9) c
	jr		nc,ai_medium_play_card_cond1_quarry
validate_magic:
	ld		a,[cpu_magic_value]
	cp		9							;a-9, if a>=9 nc, else (a<9) c
	jr		nc,ai_medium_play_card_cond1_magic	
validate_dungeon:
	ld		a,[cpu_dungeon_value]
	cp		9							;a-9, if a>=9 nc, else (a<9) c
	jr		nc,ai_medium_play_card_cond1_dungeon
validate_end:
	jr.		ai_medium_play_card_cond2	;condition 1 not detected, go to check next condition



ai_medium_play_card_cond1_quarry:
	ld		a,14						;card register + 14 contains the owner quarry value
	ld		hl,validate_magic
	push	hl
	jr		ai_medium_play_card_cond1_flavorset
ai_medium_play_card_cond1_magic:
	ld		a,18
	ld		hl,validate_dungeon
	push	hl
	jr		ai_medium_play_card_cond1_flavorset
ai_medium_play_card_cond1_dungeon:
	ld		a,16
	ld		hl,validate_end
	push	hl
ai_medium_play_card_cond1_flavorset:

	push	af
	;let's check if card selected by ai is trying to increase quarry/magic/dungeon
	;tmp_buffer3 has card position in hand
	
	ld		a,[tmp_buffer3+4]
	
	call	get_card_address
	pop		af
	ld		b,0
	ld		c,a
	add		hl,bc						;hl pointing at quarry/magic/dungeon value for the card
										;this card should add anything to quarry/magic/dungeon, so must be 0 or negative (+128)
	ld		a,[hl]
	bit		7,a							;negative?
	jr		nz,ai_medium_play_card_cond1_not_fulfilled
	and		a							;0?
	jr		z,ai_medium_play_card_cond1_not_fulfilled
	;so this card it's trying to increase  quarry/magic/dungeon ... no way!... discard
	pop		hl							;restore stack
	jr.		ai_medium_play_card_discard_and_ret							

ai_medium_play_card_cond1_not_fulfilled:
	pop		hl							;restore ret value to check another condition
	jp		hl
ai_medium_play_card_cond2:

	;Special conditions 1)
	; 2 - 'Shift' card if selected but card player wall is lower than enemy wall must be discarded and not played 
	;shift card is 34   , player_wall_height vs cpu_wall_height
	ld		a,[tmp_buffer3+4]			;[tmp_buffer3+4] holds card number
	cp		33
	jr		nz,ai_medium_play_card_cond4	;it's not shift card , check next special condition
	;check if cpu wall less than player wall
	ld		a,[player_wall_height]
	ld		b,a
	ld		a,[cpu_wall_height]
	cp		b							;cpu_wall_height - player_wall_height ? cpu wall larger -> nc, player wall larger -> c
	ret		c							;player wall larger , cpu want to swap that! ... don't discard , use that card

	jr.		ai_medium_play_card_discard_and_ret							

	
ai_medium_play_card_cond4:	
	;a still holds card number value
	cp		45							;card powerburn
	jr		nz,ai_medium_play_card_cond5	;it's not powerburn card , check next special condition
	;check cpu tower>AI_CARD45_MIN_CPU_TOWER
	ld		a,[cpu_tower_height]
	cp		AI_CARD45_MIN_CPU_TOWER		;cpu_tower_height - AI_CARD45_MIN_CPU_TOWER ? c->discard : nc-> play that
	ret		nc
	
	jr.		ai_medium_play_card_discard_and_ret						
	
	
ai_medium_play_card_cond5:		
	;a still holds card number value
	cp		47
	jr		nz,ai_medium_play_card_cond6	;it's not parity , check next special condition
	;check playermagic vs cpumagic
	ld		a,[cpu_magic_value]
	ld		b,a
	ld		a,[player_magic_value]
	cp		b							;player_magic_value - cpu_magic_value ? cpu_magic_value >= player_magic_value   ->  c nz    discard
										;										cpu_magic_value == player_magic_value	->  nc z    discard
										;										cpu_magic_value < player_magic_value	->  nc nz   ret! do it!
	jr		nc,ai_medium_play_card_cond5_check2
	jr		ai_medium_play_card_cond5_discard
ai_medium_play_card_cond5_check2:
	ret		nz							;nc & nz =>  cpu magic < player magic ... apply this card, don't discard	
ai_medium_play_card_cond5_discard:	
	jr.		ai_medium_play_card_discard_and_ret						


ai_medium_play_card_cond6:
	;a still holds card number value
	cp		30
	jr		nz,ai_medium_play_card_cond7		;it's not flood water
	;check cpuwall vs playerwall
	ld		a,[player_wall_height]
	ld		b,a
	ld		a,[cpu_wall_height]
	cp		b
								;cpu_wall_height - player_wall_height ? cpu wall larger -> nc, player wall larger -> c
	jr		z,ai_medium_play_card_cond6_discard			;if equal discard
	ret		nc							;if nc, means cpu_wall higher , we can apply flooding	
ai_medium_play_card_cond6_discard:
	jr.		ai_medium_play_card_discard_and_ret

ai_medium_play_card_cond7:
	;a still holds card number value
	cp		7
	jr		nz,ai_medium_play_card_cond8				
	;check quarries
	ld		a,[player_quarry_value]
	ld		b,a
	ld		a,[cpu_quarry_value]
	cp		b							;cpu_quarry_value - player_quarry_value ? cpu_quarry_value larger -> nc
	jr		z,ai_medium_play_card_cond7_discard
	ret		c							;apply cos player_quarry_value is greater than cpu_quarry_value

ai_medium_play_card_cond7_discard:
	jr.		ai_medium_play_card_discard_and_ret	


ai_medium_play_card_cond8:
	cp		14
	jr		z,ai_medium_play_card_cond8_logic
	cp		16
	jr		nz,ai_medium_play_card_cond9							
ai_medium_play_card_cond8_logic:
	;must be discarded if playerquarry is 1
	ld		a,[player_quarry_value]
	dec		a
	jr		z,ai_medium_play_card_discard_and_ret			;if z (->a was 1) discard (don't use it!)
	ret		


ai_medium_play_card_cond9:
	cp		73							;gobling mob?
	jr		nz,ai_medium_play_card_cond10
	
	ld		a,[cpu_wall_height]
	ld		b,a
	ld		a,[cpu_tower_height]
	add		b
	cp		4							;if a<=3 (c set) discard else play
	jr		c,ai_medium_play_card_discard_and_ret			
	ret		


ai_medium_play_card_cond10:
	cp		98							;berserker?
	jr		nz,ai_medium_play_card_cond11
	;if cpu_tower <=3
	ld		a,[cpu_tower_height]
	cp		4							;if a<=3 (c set) discard else play
	jr		c,ai_medium_play_card_discard_and_ret
	ret									;no problem...apply


ai_medium_play_card_cond11:				;tremors?
	cp		12
	ret		nz

	ld		a,[player_wall_height]
	and		a
	jr		z,ai_medium_play_card_discard_and_ret
	ret



ai_medium_play_card_discard_and_ret:
	;discard
	xor		a
	ld		[tmp_buffer3+1],a			;result will be (X,0) that means ... discard!
	ret		

	
	
	
	
	
	
	
	
	
;"IF QUARRY<EQUARRY +2QUARRY ELSE +1QUARRY"	
apply_card_effects_special_card_04:
	ld		bc,QUARRY_VALUE_OFFSET
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	;ld		bc,QUARRY_VALUE_OFFSET
	add		hl,bc
	cp		[hl]
	jr		nc,apply_card_effects_special_card_04_eqgt
	ld		a,2
	jr		apply_card_effects_special_card_04_end
apply_card_effects_special_card_04_eqgt:	
	ld		a,1
apply_card_effects_special_card_04_end:
	ex		de,hl
	ld		bc,0x0901
	call	add_integer_value
	ret

;"IF QUARRY<EQUARRY QUARRY=ENEMY QUARRY"	
apply_card_effects_special_card_07:
	ld		bc,QUARRY_VALUE_OFFSET
	add		hl,bc
	push	hl										;owner quarry pointer
	ld		a,[hl]

	ex		de,hl
	
	;ld		bc,QUARRY_VALUE_OFFSET
	add		hl,bc
	push	hl										;enemy quarry pointer
	cp		[hl]									;a-[hl]
	pop		de
	pop		hl
	jr		nc,apply_card_effects_special_card_07_eqgt	;quarry<equarry?
	ld		a,[de]
	ld		[hl],a	
apply_card_effects_special_card_07_eqgt:

	ret
	


;"IF WALL=0 +6 WALL ELSE +3 WALL"
apply_card_effects_special_card_11:
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	ld		a,[hl]
	and		a
	;wall=0?
	jr		z,apply_card_effects_special_card_11_cero
	ld		a,3
	jr		apply_card_effects_special_card_11_cero_end
apply_card_effects_special_card_11_cero:
	ld		a,6
apply_card_effects_special_card_11_cero_end:	
	ld		bc,0x6300
	call	add_integer_value
	ret
	
	




;"PLAYER  LOWEST  WALL -1 DUNGEON -2 TOWER"
apply_card_effects_special_card_30:
	push	hl
	push	de
	
	ld		bc,WALL_HEIGHT_OFFSET	
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	add		hl,bc
	cp		[hl]										;a<[hl]? a=wall owner height, [hl] same for enemy
	;3 cases
	; = ... reduce both dungeons & towers	
	; < ... apply previous just for the mage's lower wall
	; > ... apply previous just for the mage's lower wall

	pop		de
	pop		hl

	jr		z,apply_card_effects_special_card_30_both	;both are losers
	jr		c,apply_card_effects_special_card_30_owner	;owner loser
	;enemy loser
	ex		de,hl			;hl has the right value now
	call	apply_card_effects_special_card_30_dungeon_and_tower
	jr		apply_card_effects_special_card_30_end
	
apply_card_effects_special_card_30_owner:
	;hl has the right value
	call	apply_card_effects_special_card_30_dungeon_and_tower
	jr		apply_card_effects_special_card_30_end

apply_card_effects_special_card_30_both:
	;hl has the right value
	call	apply_card_effects_special_card_30_dungeon_and_tower
	ex		de,hl			;hl has the right value now
	call	apply_card_effects_special_card_30_dungeon_and_tower
apply_card_effects_special_card_30_end:

	ret



;hl base var mem to modify (owner or enemy)
apply_card_effects_special_card_30_dungeon_and_tower:
	push	hl
	ld		bc,DUNGEON_VALUE_OFFSET
	add		hl,bc
	ld		a,129 										;-1
	ld		bc,0x0901
	call	add_integer_value
	
	pop		hl
	ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	ld		a,130										;-2
	ld		bc,0x6300
	call	add_integer_value

	ret
	

	
	
	
	
;"+6 FOES +8 WALL IF DUNG <EDUNG  +1DUNG"
apply_card_effects_special_card_31:
	
	push	hl
	ld		bc,FOES_VALUE_OFFSET
	add		hl,bc
	ld		bc,0x6300
	ld		a,6
	call	add_integer_value
	pop		hl
	
	push	hl
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	ld		bc,0x6300
	ld		a,8
	call	add_integer_value
	pop		hl
	

	ld		bc,DUNGEON_VALUE_OFFSET
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	;ld		bc,DUNGEON_VALUE_OFFSET
	add		hl,bc
	cp		[hl]
	jr		nc,apply_card_effects_special_card_31_eqgt
	ex		de,hl
	ld		bc,0x0901
	ld		a,1
	call	add_integer_value
apply_card_effects_special_card_31_eqgt:	

	ret
	

;"SWITCH  YOU WALL WITH   ENEMY   WALL"
apply_card_effects_special_card_33:
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	
	ld		a,[hl]
	push	af									;owner wall saved
	
	ex		de,hl
	add		hl,bc
												;hl=enemy wall height pointer, de=owner wall height pointer
	ld		a,[hl]
	ld		[de],a								;owner wall populated
	pop		af									;retrieving owner original wall height 
	ld		[hl],a								;to assign to enemy wall height var

	ret
	
	
;"ALL PLAYERS MAGIC = HIGHEST PLAYER MAGIC"
apply_card_effects_special_card_47:
	
	ld		bc,MAGIC_VALUE_OFFSET
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	add		hl,bc
	
	cp		[hl]								;what's the highest magic?	
	jr		c,apply_card_effects_special_card_47_enemy_highest
	;equal or owner has highest
	ld		[hl],a								;hl had enemy's address, a owner value
	jr		apply_card_effects_special_card_47_end	;TODO: fix this kind of code as ret if it is readable ...	
apply_card_effects_special_card_47_enemy_highest:
	ld		a,[hl]								;save highest value (from enemy)
	ex		de,hl								;hl now has owner's address
	ld		[hl],a								
apply_card_effects_special_card_47_end:	

	ret
	
	
	
;"IF TOWER<ETOWER +2TOWER ELSE +1TOWER"
;TODO: this type of logic is repeated many times ... 
apply_card_effects_special_card_63:
	ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	;ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	cp		[hl]
	jr		nc,apply_card_effects_special_card_63_eqgt
	ld		a,2
	jr		apply_card_effects_special_card_63_end
apply_card_effects_special_card_63_eqgt:	
	ld		a,1
apply_card_effects_special_card_63_end:
	ex		de,hl
	ld		bc,0x6300
	call	add_integer_value

	ret


;"IFTOWER>EWALL 8DAMG ETOWER ELSE 8DAMAGE"
apply_card_effects_special_card_66:
	push	de
	
	ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	ld		a,[hl]
	
	ex		de,hl
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	cp		[hl]								
	ld		a,128+8					;-8		;flags set, don't modify
	pop		hl								;hl holds enemy base

	jr		z,apply_card_effects_special_card_66_eqlt
	jr		c,apply_card_effects_special_card_66_eqlt		;a=<[hl]
	;a>[hl]
	;8 damage ETower
	ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	ld		bc,0x6300				;a set (-8), bc set , hl set (enemy tower address )
	call	add_integer_value
	ret

apply_card_effects_special_card_66_eqlt:	
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	ld		bc,0x6300				;a (-8) set, bc set , hl set
	call	hit_wall_and_tower

	ret




;"IF EWALL=0 10 DAMAGE ELSE 6 DAMAGE"
apply_card_effects_special_card_86
	ld		bc,WALL_HEIGHT_OFFSET
	ex		de,hl
	add		hl,bc
	ld		a,[hl]
	and		a
	
	jr		z,apply_card_effects_special_card_86_zero
	ld		a,6+128
	jr		apply_card_effects_special_card_86_end
apply_card_effects_special_card_86_zero:
	ld		a,10+128	
apply_card_effects_special_card_86_end:
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower

	ret




;"IF EWALL>0 10 DAMAGE ELSE 7 DAMAGE"
apply_card_effects_special_card_88
	ld		bc,WALL_HEIGHT_OFFSET
	ex		de,hl
	add		hl,bc
	ld		a,[hl]
	and		a
	
	jr		z,apply_card_effects_special_card_88_zero
	ld		a,10+128
	jr		apply_card_effects_special_card_88_end
apply_card_effects_special_card_88_zero:
	ld		a,7+128
apply_card_effects_special_card_88_end:
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower	

	ret
	
	
	
	
;"IF MAGIC>EMAGIC 12 DAMAGE ELSE 8 DAMAGE"
apply_card_effects_special_card_89
	push	de
	ld		bc,MAGIC_VALUE_OFFSET
	add		hl,bc
	ld		a,[hl]

	ex		de,hl
	add		hl,bc
	cp		[hl]								;a=magic>emagic=[hl]? a-[hl]
	
	jr		c,apply_card_effects_special_card_89_a
	jr		z,apply_card_effects_special_card_89_a
	ld		a,12+128
	jr		apply_card_effects_special_card_89_end
apply_card_effects_special_card_89_a:
	ld		a,8+128	
apply_card_effects_special_card_89_end:
	ld		bc,WALL_HEIGHT_OFFSET
	pop		hl			
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower	

	ret
	
	
	

;"IF WALL>EWALL 6 DAMG ETOWER ELSE 6 DAMG"
apply_card_effects_special_card_90
	push	de
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	ld		a,[hl]

	ex		de,hl
	add		hl,bc
	cp		[hl]								;a=wall>ewall=[hl]? a-[hl]

	ld		a,6+128	
	pop		hl
	jr		c,apply_card_effects_special_card_90_a
	jr		z,apply_card_effects_special_card_90_a
	ld		bc,TOWER_HEIGHT_OFFSET
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower	
	
	ret

apply_card_effects_special_card_90_a:
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower

	ret



;"IF WALL>EWALL 3 DAMAGE ELSE 2 DAMAGE"
apply_card_effects_special_card_96
	push	de
	ld		bc,WALL_HEIGHT_OFFSET
	add		hl,bc
	ld		a,[hl]

	ex		de,hl
	add		hl,bc
	cp		[hl]								;a=wall>ewall=[hl]? a-[hl]

	pop		hl
	jr		c,apply_card_effects_special_card_96_a
	jr		z,apply_card_effects_special_card_96_a
	add		hl,bc
	ld		a,3+128	
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower	
	
	ret

apply_card_effects_special_card_96_a:
	add		hl,bc
	ld		a,2+128
	ld		bc,0x6300				;a set, bc set , hl set
	call	hit_wall_and_tower

	ret





	
;ix pointer to card
;hl pointer to owner mem
;de pointer to enemy mem
;card cost must be already applied
apply_card_effects_special_card:
	ld		a,[card_number]			;card number?
	cp		04						;mother lode?
	call	z,apply_card_effects_special_card_04
	cp		07						;copping tech?
	call	z,apply_card_effects_special_card_07
	cp		11						;foundations?
	call	z,apply_card_effects_special_card_11
	cp		30						;flood water?
	call	z,apply_card_effects_special_card_30
	cp		31						;barracks?
	call	z,apply_card_effects_special_card_31
	cp		33						;shift?
	call	z,apply_card_effects_special_card_33
	cp		47						;parity?
	call	z,apply_card_effects_special_card_47
	cp		63						;bag of bubbles?
	call	z,apply_card_effects_special_card_63
	cp		66						;lighting shard?
	call	z,apply_card_effects_special_card_66
	cp		86						;SPIZZER
	call	z,apply_card_effects_special_card_86
	cp		88						;CORROSIONCLOUD
	call	z,apply_card_effects_special_card_88
	cp		89						;UNICORN
	call	z,apply_card_effects_special_card_89
	cp		90						;ELVEN ARCHERS
	call	z,apply_card_effects_special_card_90
	cp		96						;SPEARMAN
	call	z,apply_card_effects_special_card_96

	ld		a,1						;ret a=1 , card applied

	call	fire_buildingup_fx
	call	fire_debris_fx

	call	update_Y_flags_coord

	ret






;a	card number
;checks who's the card owner (turn 0 player , 1 cpu)
;returns
;a =0 if card effects couldn't be applied , a=1 if it could 
;updates play_again var always
apply_card_effects:
	ld		[card_number],a								;saved to know which card when it's a special one

	push	af	
	call	check_can_play_card
	and		a				;return 0 (false)?
	jr		nz,apply_card_effects_enough_resources
	pop		af
	;TODO: sfx bad card selection!
	xor		a				;ret a=0 , it couldn't be applied
	
	;it's not needed to redraw towers/wall status	
	ret
	
	
apply_card_effects_enough_resources:


	ld		b,9
	call	INICIA_EFECTO


	call	capture_main_playing_vars_values

	pop		af

	call	get_card_address														;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	push	hl				
	pop		ix				;save pointer to card to ix
	
	ld		hl,turn
	ld		a,[hl]
	and		a				;0? player?
	jr		z,apply_card_effects_player
							;cpu owner
	ld		hl,cpu_tower_height 	;card owner vars pointer set on hl					
	ld		de,player_tower_height	;enemy owner vars pointer set on de
					
	jr		apply_card_effects_player_already_set
	
apply_card_effects_player:
							;player owner
	ld		hl,player_tower_height 	;card owner vars pointer set on hl					
	ld		de,cpu_tower_height		;enemy owner vars pointer set on de

apply_card_effects_player_already_set:



							;ix pointer to card
							;hl pointer to owner mem
							;de pointer to enemy mem		
;checks if forced to drop flag
	ld		a,[ix]			; flags 1
	bit		0,a				;forced to drop?
	jr		z,apply_card_effects_not_force_to_drop
	ld		a,2				;forced_to_drop has 2 steps
	jr		apply_card_effects_any_force_to_drop_apply
apply_card_effects_not_force_to_drop:
	xor		a
apply_card_effects_any_force_to_drop_apply:	
	ld		[forced_to_drop],a



							;ix pointer to card
							;hl pointer to owner mem
							;de pointer to enemy mem		
	ld		a,[ix+1]		;flags 2
;updates play_again flag
	bit		3,a
	push	af
	jr		z,apply_card_effects_not_play_again
							;set play_again	
	ld		a,1
	ld		[play_again],a			;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	jr		apply_card_effects_play_again_end
apply_card_effects_not_play_again:	
						;unset play_again
	xor		a		
	ld		[play_again],a			;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

apply_card_effects_play_again_end:	
	pop		af
	bit		0,a				;brown?
	jr		nz,apply_card_effects_brown
	bit		1,a				;blue?
	jr		nz,apply_card_effects_blue
							;green
	ld		c,FOES_VALUE_OFFSET
	jr		apply_card_effects_color_done
apply_card_effects_brown:
	ld		c,BRICKS_VALUE_OFFSET
	jr		apply_card_effects_color_done
apply_card_effects_blue:
	ld		c,GEMS_VALUE_OFFSET
	jr		apply_card_effects_color_done
apply_card_effects_color_done:								
	ld		a,[ix+3]				;cost
	set		7,a						;negative
	
	push	hl
	ld		b,0
	;c already set
	add		hl,bc
	ld		bc,0xff00				;a set, bc set , hl set
	call	add_integer_value
	pop		hl
	
	
	;special card?;;;;
	bit		5,[ix+1]
	jr.		nz,apply_card_effects_special_card    	;jump with 
													;ix pointer to card
													;hl pointer to owner mem
													;de pointer to enemy mem	
	;;;;;;;;;;;;;;;;;;
	
	
	
	
	push	hl
	ld		a,[ix+4]				;owner tower
	ld		b,0
	ld		c,TOWER_HEIGHT_OFFSET
	push	bc	
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x6300
	ld		a,[ix+6]				;enemy tower
	call	add_integer_value
	pop		hl
	
	
	
	
	

	
	;
	; Ok, now wall stuff
	; We must take into account when 'damage just wall' flag is set
	
	push	hl
	ld		a,[ix+5]				;owner wall
	ld		b,0
	ld		c,WALL_HEIGHT_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	
	push	de						;save de, hit_wall_and_tower modifies that
	;push	af
	
	ld		d,[ix]
	bit		1,d
	jr		nz,apply_card_effects_just_wall
	
	call	hit_wall_and_tower
	jr		add_integer_value_just_wall_done
apply_card_effects_just_wall:

	call	add_integer_value
add_integer_value_just_wall_done:

	;pop		af
	pop		de
	
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x6300
	ld		a,[ix+7]				;enemy wall
	push	de
	

	ld		d,[ix]
	bit		1,d
	jr		nz,apply_card_effects_just_wall_2
	
	call	hit_wall_and_tower
	jr		add_integer_value_just_wall_done_2
apply_card_effects_just_wall_2:

	call	add_integer_value
add_integer_value_just_wall_done_2:

	
	pop		de
	pop		hl
	
	
	;
	
	
	push	hl
	ld		a,[ix+8]				;owner bricks
	ld		b,0
	ld		c,BRICKS_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x6300
	ld		a,[ix+9]				;enemy bricks
	call	add_integer_value	
	pop		hl

	push	hl
	ld		a,[ix+10]				;owner foes
	ld		b,0
	ld		c,FOES_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x6300
	ld		a,[ix+11]				;enemy foes
	call	add_integer_value

	pop		hl

	push	hl
	ld		a,[ix+12]				;owner gems
	ld		b,0
	ld		c,GEMS_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x6300				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x6300
	ld		a,[ix+13]				;enemy gems
	call	add_integer_value	
	pop		hl	
	
	push	hl
	ld		a,[ix+14]				;owner quarry
	ld		b,0
	ld		c,QUARRY_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x0901				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x0901
	ld		a,[ix+15]				;enemy quarry
	call	add_integer_value	
	pop		hl	
		
	push	hl
	ld		a,[ix+16]				;owner dungeon
	ld		b,0
	ld		c,DUNGEON_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x0901				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x0901
	ld		a,[ix+17]				;enemy dungeon
	call	add_integer_value		
	pop		hl	
	
	push	hl
	ld		a,[ix+18]				;owner magic
	ld		b,0
	ld		c,MAGIC_VALUE_OFFSET
	push	bc
	add		hl,bc
	ld		bc,0x0901				;a set, bc set , hl set
	call	add_integer_value
	pop		bc
	ld		h,d
	ld		l,e
	add		hl,bc					;enemy var (de+bc)
	ld		bc,0x0901
	ld		a,[ix+19]				;enemy magic
	call	add_integer_value	
	pop		hl	


	;update tower/wall status on screen setting redrawing flag
	ld		a,[dump_flags]
	or		0x04
	ld		[dump_flags],a

	call	update_Y_flags_coord

	call	fire_buildingup_fx
	call	fire_debris_fx

	ld		a,1						;ret a=1 , card applied
						
	ret








;TODO: reusing shop_topcards_template to hold previous values
;Uses shop_topcards_template to store towers,walls and big counters values before card effects being applied
capture_main_playing_vars_values:
	ld		hl,shop_topcards_template
	
	ld		a,[player_tower_height]
	ld		[hl],a
	inc		hl

	ld		a,[cpu_tower_height]
	ld		[hl],a
	inc		hl

	ld		a,[player_wall_height]
	ld		[hl],a
	inc		hl

	ld		a,[cpu_wall_height]
	ld		[hl],a
	inc		hl

	ld		a,[player_dungeon_value]
	ld		[hl],a
	inc		hl

	ld		a,[cpu_dungeon_value]
	ld		[hl],a
	inc		hl
	
	ld		a,[player_magic_value]
	ld		[hl],a
	inc		hl

	ld		a,[cpu_magic_value]
	ld		[hl],a
	inc		hl

	ld		a,[player_quarry_value]
	ld		[hl],a
	inc		hl
	
	ld		a,[cpu_quarry_value]
	ld		[hl],a

	ret



fire_buildingup_fx:
;compares previous main vars on shop_topcards_template with the current values. If something is different and effect will be triggered
	ld		hl,shop_topcards_template
	ld		b,[hl]
	ld		a,[player_tower_height]
	cp		b
	jr		z,fire_buildingup_fx_check2
	jr		nc,fire_buildingup_fx_buildup_sound
fire_buildingup_fx_check2:
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_tower_height]
	cp		b	
	jr		z,fire_buildingup_fx_check3
	jr		nc,fire_buildingup_fx_buildup_sound
fire_buildingup_fx_check3:	
	inc		hl
	ld		b,[hl]
	ld		a,[player_wall_height]
	cp		b	
	jr		z,fire_buildingup_fx_check4
	jr		nc,fire_buildingup_fx_buildup_sound
fire_buildingup_fx_check4:	
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_wall_height]
	cp		b	
	ret		z
	ret		c
		
fire_buildingup_fx_buildup_sound:	
	
	;ld		a,11
	;call	INICIA_SONIDO	
	ld		b,11
	call	INICIA_EFECTO
	
	ret




;TODO: optimize and reduce
;compares previous main vars on shop_topcards_template with the current values. If something is different and effect will be triggered
fire_debris_fx:
	ld		hl,shop_topcards_template
	ld		b,[hl]
	ld		a,[player_tower_height]
	cp		b
	jr		c,fire_debris_fx_pt
	
fire_debris_fx_step1:	
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_tower_height]
	cp		b
	jr		c,fire_debris_fx_ct

fire_debris_fx_step2:
	inc		hl
	ld		b,[hl]
	ld		a,[player_wall_height]
	cp		b
	jr.		c,fire_debris_fx_pw

fire_debris_fx_step3:
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_wall_height]
	cp		b
	jr.		c,fire_debris_fx_cw

;--------------
fire_debris_fx_step4:
	inc		hl
	ld		b,[hl]
	ld		a,[player_dungeon_value]
	cp		b
	jr.		c,fire_debris_fx_pd
	
fire_debris_fx_step5:	
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_dungeon_value]
	cp		b
	jr.		c,fire_debris_fx_cd

fire_debris_fx_step6:
	inc		hl
	ld		b,[hl]
	ld		a,[player_magic_value]
	cp		b
	jr.		c,fire_debris_fx_pm

fire_debris_fx_step7:
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_magic_value]
	cp		b
	jr.		c,fire_debris_fx_cm

fire_debris_fx_step8:
	inc		hl
	ld		b,[hl]
	ld		a,[player_quarry_value]
	cp		b
	jr.		c,fire_debris_fx_pq

fire_debris_fx_step9:
	inc		hl
	ld		b,[hl]
	ld		a,[cpu_quarry_value]
	cp		b
	jr.		c,fire_debris_fx_cq


;sfx
	ld		hl,debris_fx_struct
	ld		a,[hl]
	dec		a
	jr		z,fire_debris_fx_crumble
	inc		hl
	ld		a,[hl]
	dec		a
	jr		z,fire_debris_fx_crumble
	inc		hl
	ld		a,[hl]
	dec		a
	jr		z,fire_debris_fx_crumble
	inc		hl
	ld		a,[hl]
	dec		a
	jr		z,fire_debris_fx_crumble
	ret

fire_debris_fx_crumble:

	;ld		a,10
	;call	INICIA_SONIDO
	ld		b,10
	call	INICIA_EFECTO


	ret

;---------------------------

fire_debris_fx_pt:
	push	hl
	ld		hl,debris_fx_struct
	ld		a,1
	ld		[hl],a
	
	xor		a
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct],a					;Y
	ld		a,b
	ld		[debris_fx_spr_struct+2],a					;scene
	
	pop		hl
	jr.		fire_debris_fx_step1

fire_debris_fx_ct:
	push	hl
	ld		hl,debris_fx_struct+1
	ld		a,1
	ld		[hl],a

;	ld		a,1
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+4],a
	ld		a,b
	ld		[debris_fx_spr_struct+6],a


	pop		hl
	jr.		fire_debris_fx_step2

fire_debris_fx_pw:
	push	hl
	ld		hl,debris_fx_struct+2
	ld		a,1
	ld		[hl],a

	ld		a,2
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+8],a
	ld		a,b
	ld		[debris_fx_spr_struct+10],a


	pop		hl
	jr.		fire_debris_fx_step3

fire_debris_fx_cw:
	push	hl
	ld		hl,debris_fx_struct+3
	ld		a,1
	ld		[hl],a

	ld		a,3
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+12],a
	ld		a,b
	ld		[debris_fx_spr_struct+14],a


	pop		hl
	jr.		fire_debris_fx_step4



fire_debris_fx_pd:
	push	hl
	ld		hl,debris_fx_struct+4
	ld		a,1
	ld		[hl],a

	ld		a,4
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+16],a
	ld		a,b
	ld		[debris_fx_spr_struct+18],a


	pop		hl
	jr.		fire_debris_fx_step5

fire_debris_fx_cd:
	push	hl
	ld		hl,debris_fx_struct+5
	ld		a,1
	ld		[hl],a
	
	ld		a,5
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+20],a
	ld		a,b
	ld		[debris_fx_spr_struct+22],a

	
	pop		hl
	jr.		fire_debris_fx_step6

fire_debris_fx_pm:
	push	hl
	ld		hl,debris_fx_struct+6
	ld		a,1
	ld		[hl],a
	
	ld		a,6
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+24],a
	ld		a,b
	ld		[debris_fx_spr_struct+26],a

	
	pop		hl
	jr.		fire_debris_fx_step7
	
fire_debris_fx_cm:
	push	hl
	ld		hl,debris_fx_struct+7
	ld		a,1
	ld		[hl],a
	
	ld		a,7
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+28],a
	ld		a,b
	ld		[debris_fx_spr_struct+30],a

	
	pop		hl
	jr.		fire_debris_fx_step8

fire_debris_fx_pq:
	push	hl
	ld		hl,debris_fx_struct+8
	ld		a,1
	ld		[hl],a

	ld		a,8
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+32],a
	ld		a,b
	ld		[debris_fx_spr_struct+34],a


	pop		hl
	jr.		fire_debris_fx_step9

fire_debris_fx_cq:
	push	hl										;TODO: ???really needed it?
	ld		hl,debris_fx_struct+9
	ld		a,1
	ld		[hl],a

	ld		a,9
	call	get_y_debris_and_first_scene_fx
	ld		[debris_fx_spr_struct+36],a
	ld		a,b
	ld		[debris_fx_spr_struct+38],a


	pop		hl										;TODO: ???really needed it?

	ret



;a = position on array
;ret a=initial Y, b=first scene
get_y_debris_and_first_scene_fx:
	
	add		a,a
	add		a,a								;a=a*4
	ld		b,0
	ld		c,a
	ld		hl,debris_initial_values
	add		hl,bc
	ld		a,[hl]
	inc		hl
	inc		hl
	ld		b,[hl]

	ret






DEBRIS_FX_MAX_COUNTER	equ	5


init_debris_structs:

	xor		a					;initial status
	ld		hl,debris_fx_struct
	ld		[hl],a
	ld		d,h
	ld		e,l
	inc		de
	ld		bc,9
	ldir



	ld		a,DEBRIS_FX_MAX_COUNTER				;initial counter
	ld		hl,debris_fx_struct+10
	ld		[hl],a
	ld		d,h
	ld		e,l
	inc		de
	ld		bc,9
	ldir
	

	;debris_fx_spr_struct
	ld		hl,debris_initial_values
	ld		de,debris_fx_spr_struct
	ld		bc,40
	ldir

	ld		b,10
	ld		hl,debris_fx_spr_struct
	ld		a,193
init_debris_structs_loop:
	ld		[hl],a
[4]	inc		hl
	djnz	init_debris_structs_loop


	ret







update_debris_status_and_scenes:

	ld		b,10
	ld		hl,debris_fx_struct+9
	ld		de,debris_fx_spr_struct+(9*4)
update_debris_status_and_scenes_walltower_loop:
	push	bc
	push	hl
	push	de
	call	update_walltowerbigcounters_debris_fx
	pop		de
	pop		hl
	dec		hl								;next wall/tower
[4]	dec		de
	pop		bc
	
	djnz	update_debris_status_and_scenes_walltower_loop


	ret




;TODO: very similar to the previous routine ... think of making something smaller merging them
;hl pointer to debris_fx_struct position
;de pointer to debris_fx_spr_struct position
;b plane
;uses font_buffer as temp buffer (2 bytes) TODO: Change name!!!
update_walltowerbigcounters_debris_fx:	
	ld		a,b
	ld		[font_buffer+2],a				;save postion number
	ld		a,[hl]
	and		a
	ret		z								;status 0 , return
	;update counter
	ld		[font_buffer],hl				;save state position
	ld		bc,0x0A
	add		hl,bc							;hl points at counter
	dec		[hl]
	ret		nz								;didn't reach 0, ret!
	
	;0! update counter
	ld		a,DEBRIS_FX_MAX_COUNTER
	ld		[hl],a							;counter updated
	;next state
	ld		hl,[font_buffer]				;restore state pointer
	ld		a,[hl]
	inc		a
	cp		5								;states 0,1,2,3,4
	jr		nz,update_walltowerbigcounters_debris_fx_staterefresh
	;5! , must be set to 0
	ld		a,193
	ld		[de],a							;hide it
[2]	inc		de								;de pointing scene
	ld		a,76							;first scene
	ld		[de],a
	xor		a								;next state ... 0 (off)
	jr		update_walltowerbigcounters_debris_fx_end
update_walltowerbigcounters_debris_fx_staterefresh:
	push	af

	;REFRESH Y coord
	ld		a,[font_buffer+2]
	dec		a
	add		a,a
	add		a,a								;a=a*4
	ld		b,0
	ld		c,a
	push	hl
	ld		hl,debris_initial_values
	add		hl,bc
	ld		a,[hl]
	pop		hl
	ld		[de],a							;Y refreshed

[2]	inc		de								;de pointing at scene
	ld		a,[de]
	add		4
	ld		[de],a							;spr1 new scene set!


	pop		af								;restore next state
update_walltowerbigcounters_debris_fx_end:
	ld		[hl],a							;set new state

	ret







;a card number
;look int turn var to know whether player or cpu
;return a=0 false, a=1 true
check_can_play_card:
	
	call	get_card_address										;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	inc		hl				; flags address

	ld		a,[turn]
	and		a				;player or cpu?
	
	jr		z,check_can_play_card_player
							;cpu
	ld		de,cpu_tower_height
	jr		check_can_play_card_playerorcpu_end
check_can_play_card_player:
							;player
	ld		de,player_tower_height
check_can_play_card_playerorcpu_end:
	push	de
	pop		ix				;ix holds base var address
	
	ld		a,[hl]
	bit		0,a
	jr		nz,check_can_play_card_brown
	bit		1,a
	jr		nz,check_can_play_card_blue
							;green
	ld		a,[ix+FOES_VALUE_OFFSET]	;how many foes has player/cpu?
	jr		check_can_play_card_color_end
check_can_play_card_brown:
	ld		a,[ix+BRICKS_VALUE_OFFSET]	;how many bricks has player/cpu?
	jr		check_can_play_card_color_end
check_can_play_card_blue:
	ld		a,[ix+GEMS_VALUE_OFFSET]	;how many gems has player/cpu?

check_can_play_card_color_end:
	inc		hl
	inc		hl							;hl points at card cost	
	cp		[hl]						;a<[hl] ? actual number of bricks/gems/foes < card cost?
	jr		c,check_can_play_card_false
	ld		a,1
	ret
check_can_play_card_false:
	xor		a
	ret






;a value to add (or substract)
;bc b max value , c lower value
;hl	 wall mem address
;modifies de,af
hit_wall_and_tower:
	bit		7,a
	jr		z,hit_wall_and_tower_add
	res		7,a				;positive
	
	push	af
	ld		a,[hl]
	pop		de
	cp		d				;a=parm:[hl]=currentwall < d=parm:a=value to add/substract	?
	jr		c,hit_wall_and_tower_hitwall
	ld		a,d				
	set		7,a				;a set, hl set, bc set
	jr		hit_wall_and_tower_add

hit_wall_and_tower_hitwall:
	ld		e,a				;e=currentwall (small value)
	ld		a,d				;a=hit value (big value)
	sub		e				
	set		7,a
	ld		[hl],0			;wall=0
	dec		hl				;pointing at tower
							;a set. hl set , bc set (parm)

hit_wall_and_tower_add:
	call	add_integer_value	;hit 
	ret





;[hl] = [hl] + a 
;a value to add (or substract)
;bc b max value , c lower value
;hl	 mem address
;checks overflows
;doesn't modify hl.de
add_integer_value:
	bit		7,a			;pos or neg?
	jr		nz,add_integer_value_neg
						;pos
	add		a,[hl]		
	jr		c,add_integer_value_top_overflow	;jmp if overflow
	cp		b
	jr		c,add_integer_value_top_ok
	jr		nz,add_integer_value_top_overflow
add_integer_value_top_ok:
	ld		[hl],a
	ret					
	
add_integer_value_top_overflow:
	ld		[hl],b	;top value
	ret

add_integer_value_neg:
						;neg	
	push	de
	push	af
	ld		a,[hl]		;big mem val
	pop		de			;d = original -a	
	res		7,d
	sub		a,d			;[hl]-a
	jr		c,add_integer_value_low_overflow	;jmp if overflow		
	cp		c
	jr		c,add_integer_value_low_overflow
	ld		[hl],a
	pop		de
	ret
	
add_integer_value_low_overflow:
	ld		[hl],c					;set lower val
	pop		de
	ret










;return a=0 if player couldn't be played ,a!=0 if it could
play_player_selected_card:

	ld		hl,cursor_data+1
	ld		a,[hl]
	ld		hl,player_hand
	ld		b,0
	ld		c,a
	add		hl,bc
	
	ld		a,[hl]
	call	apply_card_effects
	
	;sfx and delay
	
	;discard
	push	af
	and		a									;apply_card_effects rets a=0 if card couldn't be played
	ld		a,0									;keep f reg, a=0 is don't check 'don't drop flag'
	call	nz,discard_player_selected_card		;discard card just if it was played
	;refresh
	;TODO get rid of excesive refresh
	;call	display_two_digits_counters
	;call	display_one_digits_counters
	;call	display_towers_walls

	pop		af
	

	
	ret




; a=0 don't check drop flag, a=1 check it 
;returns a=0 if couldn't be dropped , a=1 if it could
discard_player_selected_card:
	
	ld		[tmp_buffer],a	
	
	;ld		h,MAX_CARDS_GAME
	;ld		l,MASK_MAX_CARDS_GAME
	;call	rand_max
	call	select_random_card_for_player
	
	
	push	af				;save random next card
	
	ld		hl,cursor_data+1
	ld		a,[hl]
	
	ld		hl,player_hand
	ld		b,0
	ld		c,a
	add		hl,bc
	
	push	hl

	; are we gonna check 'don't drop flag?'
	xor		a
	push	hl
	ld		hl,tmp_buffer	
	cp		[hl]
	pop		hl
	jr		z,discard_player_selected_card_drop		;don't check 'don't drop flag'

	;check that flag
	ld		a,[hl]
	call	get_card_address															;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
	inc		hl				; flags address

	ld		a,[hl]
	bit		4,a
	jr		z,discard_player_selected_card_drop
	
	pop		hl
	pop		af				;stack restored
	xor		a				;ret a=0
	ret

discard_player_selected_card_drop:
	pop		hl
	pop		af				;restore random next card

	;ld		[hl],a			
	
	;call	discard sfx ;TODO
	ld		[hl],a
	push	af
	call	display_player_hand							;TODO: check if we can render this later
	;a card number
	;l (LCARDART_F_TILE or RCARDART_F_TILE)
	pop		af
	ld		l,LCARDART_F_TILE
	call	print_card
	halt
	call	display_card
	
	
	ld		a,[forced_to_drop]							;it could be 0,1 or 2
	cp		0
														;if a > 0 forced_to_drop flag
	jr		z,discard_player_selected_card_drop_end		;if forced_to_drop == 0 ==> exit
	dec		a											;now forced_to_drop is 1 or 0 after dec
	ld		[forced_to_drop],a							;save forced_to_drop flag
	;and		a											;if forced_to_drop==0, it means used to be 1 few steps ago
	;jr		nz,discard_player_selected_card_drop_end		;so, preserve forced_to_drop flag to 1
	ld		a,1											;if forced_to_drop==1 it means used to be 2	
	ld		[play_again],a								;and set play again for next turn
	xor		a
	;ret	a==0 to check play again condition
	ret
	
discard_player_selected_card_drop_end:	
	ld		a,1				;ret 1

	ret



;a = cpu hand position
discard_cpu_card:
	push	af
	
	;ld		h,MAX_CARDS_GAME
	;ld		l,MASK_MAX_CARDS_GAME
	;call	rand_max
	ld		hl,[enemy_current_deck_pointer]
	call	select_random_card_for_ai
	
	ld		d,a					;next random card on d
	
	pop		af					;restore a = hand position
	
	ld		hl,cpu_hand
	ld		b,0
	ld		c,a
	add		hl,bc				;hl pointing at cpu_hand right position
	
	;call	show_discard_card	;TODO:
	;call	sfx_cpu_drop
	ld		[hl],d

	ret




rand:
	push	hl
	/*
	ld		hl,[seed]
	add		hl,hl
	sbc		a,a
	and		0x83
	xor		l
	ld		l,a
	ld		[seed],hl
	*/
	
	 ld a, (seed)
	 ld b, a 

	 rrca ; multiply by 32
	 rrca
	 rrca
	 xor 0x1f

	 add a, b
	 sbc a, 255 ; carry

	 ld (seed), a
	 	
	
	
	
	pop		hl
	
	ret



init_rand:
	ld		a,[JIFFY]
	or		0x80
	ld		[seed],a
	
	ret



;input
;h max rand 
;l power of 2 mask
;return
;a rand number between 0 and h
rand_max:
	push	hl
	call	rand
	;call	good_rand
	and		l				;apply mask , so rand = rand AND mask = very close number
	pop		hl
	cp		h				;rand with mask > max rand?
	jr		nc,rand_max		;retry :-(

	ret




/*
refresh_good_rand:
	call	init_rand
	ld		b,255
	ld		hl,font_buffer
good_rand_loop:
	call	rand
	ld		[hl],a
	inc		hl
	djnz	good_rand_loop

	ret
	
	
good_rand:
	push	bc
	push	hl
	ld		hl,good_rand_offset
	inc		[hl]
	ld		a,[hl]

	ld		hl,font_buffer
	
	ld		b,0
	ld		c,a
	
	add		hl,bc

	ld		a,[hl]
	pop		hl
	pop		bc
	ret
*/








; this routine performs the operation HL=D*E
multiply:                        
	ld hl,0                        ; HL is used to accumulate the result
	ld a,d                         ; checking one of the factors; returning if it is zero
	or a
	ret z
	ld b,d                         ; one factor is in B
	ld d,h                         ; clearing D (H is zero), so DE holds the other factor
MulLoop:                         ; adding DE to HL exactly B times
	add hl,de
	djnz MulLoop
	
	ret

	
	
	
init_player_and_cpu_hand:
	;random cards for player
	ld		hl,player_hand
	call	select_random_card_for_player	
	ld		[hl],a
	inc		hl
	call	select_random_card_for_player
	ld		[hl],a
	inc		hl
	call	select_random_card_for_player
	ld		[hl],a
	inc		hl
	call	select_random_card_for_player
	ld		[hl],a
	inc		hl
	call	select_random_card_for_player
	ld		[hl],a
	inc		hl
	call	select_random_card_for_player
	ld		[hl],a
	

	;random cards for enemy
	ld		hl,[enemy_current_deck_pointer]
	call	select_random_card_for_ai
	ld		[cpu_hand],a
	call	select_random_card_for_ai
	ld		[cpu_hand+1],a
	call	select_random_card_for_ai
	ld		[cpu_hand+2],a
	call	select_random_card_for_ai
	ld		[cpu_hand+3],a
	call	select_random_card_for_ai
	ld		[cpu_hand+4],a

	call	select_random_card_for_ai
	ld		[cpu_hand+5],a
	
	ret	
	
	
	
load_cards_regs:
	ld		hl,cards_regs_packed
	ld		de,cards_regs
	call	unpack
	
	ret


;For every single battle...
;TODO: initialization will be different depending on type of enemy, bonuses collected by the player, etc
init_vars_for_battle:
	ld		a,25
	ld		[player_tower_height],a
	ld		[cpu_tower_height],a

	ld		a,1
	ld		[player_dungeon_value],a
	ld		[player_magic_value],a
	ld		[cpu_magic_value],a
	ld		[cpu_dungeon_value],a
	ld		[player_quarry_value],a
	ld		[cpu_quarry_value],a



	ld		a,15
	ld		[cpu_foes_value],a
	ld		[player_gems_value],a
	ld		[cpu_gems_value],a
	ld		[player_bricks_value],a
	ld		[cpu_bricks_value],a
	ld		[player_wall_height],a
	ld		[player_foes_value],a
	ld		[cpu_wall_height],a
		


	ld		hl,cursor_data
	ld		[hl++],0
	ld		[hl],0


	xor		a
	ld		[turn],a
	ld		[play_again],a
	ld		[forced_to_drop],a


	ret







init_vars:

	call	init_vars_for_battle
		
	ld		a,1
	ld		[music_onoff],a

	ld		hl,cursor_data
	ld		[hl++],0
	ld		[hl],0
	
	xor		a
	ld		[keyboard_pressed],a
	ld		[turn],a
	ld		[play_again],a
	ld		[dump_flags],a
	ld		[shop_filter],a
	ld		[mmenu_option],a	
	ld		[quest_current_enemy],a
	
	
	call	init_rand
	

	ld		hl,cpu_delay
	ld		[hl],120
	
	;shop
	ld		hl,shop_card_list
	xor		a
	ld		b,6
.local_loop:
	ld		[hl],a
	inc		hl
	inc		a
	djnz	.local_loop
	
	
	
	ld		hl,shop_coins
	IF DEBUG_MODE==0
	ld		a,80;0xe6;0x38					;824 dec = 0x0338 hex
	ENDIF
	IF DEBUG_MODE==1
	ld		a,200
	ENDIF
	ld		[hl],a
	inc		hl
	ld		a,0;0x03
	ld		[hl],a	
	
	ret




	include	"arcomagerom64k.asm"
	include "menu.asm"	
	include "keyboard.asm"
	include "display.asm"
	include "shop.asm"
	include "scrolltext.asm"
	include	"saveloadgame.asm"
	include	"tape.asm"
	include	"unpack.asm"
	include	"WYZPROPLAY47aMSX.asm"
	;include	"sfx.asm"
	include	"music.asm"
	IF DEBUG_MODE==1
	include "debug.asm"
	ENDIF
;TABLA_SONG:     
;	DW      SONG_0;SONG_1		;tabla de etiquetas de los módulos. 
SONG_0:		;BATTLE MUSIC
	incbin	"../music/battle_track.mus"	
SONG_1:		;MENU MUSIC
	incbin	"../music/menu_track.mus.pletter"	
SONG_2:		;SHOP MUSIC
	incbin	"../music/shop_track.mus.pletter"
	include "cdata.asm"	
	;include "cards.asm"
cards_regs_packed:
	incbin	"binary_data/arcomage_cardsinfo.pletter.bin"

;WARNING: this must be assembled into rom third page (page 2) (above 0x8000)
	include	"pacsram.asm"



;battle_patterns_colors:
;	incbin	"binary_data/battle_tiles.bin.pletter.col"


	ds      0C000h-$,0FFh       ; Filled up 16KB	


	;page 3
	org	0xc000

title_screen_tiles:
	incbin	"binary_data/title_screen.bin.til.rle"
title_screen_colors:
	incbin	"binary_data/title_screen.bin.col.rle"
battle_patterns:
	incbin	"binary_data/battle_tiles.bin.til.rle"
battle_patterns_colors:
	incbin	"binary_data/battle_tiles.bin.col.rle"

	
shop_patterns:	
	incbin	"binary_data/shop_tiles.bin.til.rle"

finale_patterns:
	incbin	"binary_data/finale.bin.til.rle"
finale_colors:	
	incbin	"binary_data/finale.bin.col.rle"
	
	ds      10000h-$,0FFh       ; Filled up 16KB	
	
	include	"memory.asm"
